-
Notifications
You must be signed in to change notification settings - Fork 50
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
Mainnet spell 2024-10-17 #433
Conversation
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.
Left some additional comments
Good to deploy Mainnet Executive Spell Review ChecklistDevelopment Stage
Pre-Deployment Stage
|
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.
TL;DR: good to deploy
Mainnet Executive Spell Review Checklist
Development Stage
-
Preparation
- Exec Sheet for the specified date is found in the "Executive Vote Implementation Process" google sheet
https://docs.google.com/spreadsheets/d/1w_z5WpqxzwreCcaveB2Ye1PP5B8QAHDglzyxKHG3CHw/edit?gid=338754189#gid=338754189 - Using Exec Sheet URL from the above, read spell instructions from the Exec Sheet and list them below
- Setup new MkrOsm
- Whitelist MkrOsm to read from current PIP_MKR using
DssExecLib.addReaderToWhitelist
with the following parameters:- Set parameter address _oracle: PIP_MKR address from chainlog (0xdbbe5e9b1daa91430cf0772fcebe53f6c6f137df)
- Set parameter address _reader: 0x4F94e33D0D74CfF5Ca0D3a66F1A650628551C56b
- Set MkrOsm as "PIP_MKR" in the chainlog using the following parameters:
- Set parameter bytes32 _key: "PIP_MKR"
- Set parameter address _val: 0x4F94e33D0D74CfF5Ca0D3a66F1A650628551C56b
- Whitelist MkrOsm to read from current PIP_MKR using
- Setup new VoteDelegateFactory
- Rename "VOTE_DELEGATE_PROXY_FACTORY" to "VOTE_DELEGATE_FACTORY_LEGACY" in chainlog:
- Call DssExecLib.setChangelogAddress with the following parameters:
- Set parameter bytes32 _key: "VOTE_DELEGATE_FACTORY_LEGACY"
- Set parameter address _val: VOTE_DELEGATE_PROXY_FACTORY address (0xd897f108670903d1d6070fcf818f9db3615af272) from the chainlog
- Call DssExecLib.setChangelogAddress with the following parameters:
- Call CHAINLOG.removeAddress with the following parameters:
- Set parameter bytes32 _key: "VOTE_DELEGATE_PROXY_FACTORY"
- Set "VOTE_DELEGATE_FACTORY" in the chainlog to 0xC3D809E87A2C9da4F6d98fECea9135d834d6F5A0
- Rename "VOTE_DELEGATE_PROXY_FACTORY" to "VOTE_DELEGATE_FACTORY_LEGACY" in chainlog:
- Setup Lockstake Engine
- SBE Parameter Changes
- Decrease splitter "burn" rate by 30% from 100% to 70% with the following parameters:
- Decrease splitter "burn" with address _base: MCD_SPLIT from chainlog
- Decrease splitter "burn" with bytes32 _what: "burn"
- Decrease splitter "burn" with uint256 _amt: 70%
- Increase vow.hump by 5 million DAI, from 55 million DAI to 60 million DAI
- Increase splitter.hop by 4,014 seconds, from 11,635 seconds to 15,649 seconds.
- Set Flapper farm by calling FlapperInit.setFarm with the following parameters:
- Set Flapper farm with address farm_ : 0x92282235a39bE957fF1f37619fD22A9aE5507CB1
- Set Flapper farm with address splitter: MCD_SPLIT from chainlog
- Set Flapper farm with address usdsJoin: USDS_JOIN from chainlog
- Set Flapper farm with uint256 hop: 15,649
- Set Flapper farm with bytes32 prevChainlogKey: bytes32(0)
- Set Flapper farm with chainlogKey: "REWARDS_LSMKR_USDS"
- "Under the hood" actions for setting flapper:
- LsMkrUsdsFarm will be set as "farm" in MCD_SPLIT
- MCD_SPLIT will be set as "rewardsDistribution" in LsMkrUsdsFarm
- Provided "hop" will be set as "rewardsDuration" in LsMkrUsdsFarm
- New chainlog key REWARDS_LSMKR_USDS will be added
- Init Lockstake Engine by calling LockstakeInit.initLockstake with the following parameters:
- Init Lockstake Engine with address lsmkr: 0xb4e0e45e142101dC3Ed768bac219fC35EDBED295
- Init Lockstake Engine with address engine: 0x2b16C07D5fD5cC701a0a871eae2aad6DA5fc8f12
- Init Lockstake Engine with address clipper: 0xA85621D35cAf9Cf5C146D2376Ce553D7B78A6239
- Init Lockstake Engine with address clipperCalc: 0xf13cF3b39823CcfaE6C2354dA56416C80768474e
- Init Lockstake Engine with bytes32 ilk: "LSE-MKR-A"
- Init Lockstake Engine with address voteDelegateFactory: 0xC3D809E87A2C9da4F6d98fECea9135d834d6F5A0
- Init Lockstake Engine with address usdsJoin: USDS_JOIN from chainlog
- Init Lockstake Engine with address usds: USDS from chainlog
- Init Lockstake Engine with address mkr: MCD_GOV from chainlog
- Init Lockstake Engine with address mkrSky: MKR_SKY from chainlog
- Init Lockstake Engine with address sky: SKY from chainlog
- Init Lockstake Engine with address[] farms: 0x92282235a39bE957fF1f37619fD22A9aE5507CB1
- Init Lockstake Engine with uint256 fee: 5%
- Init Lockstake Engine with uint256 maxLine: 20 million DAI
- Init Lockstake Engine with uint256 gap: 5 million
- Init Lockstake Engine with uint256 ttl: 16 hours
- Init Lockstake Engine with uint256 dust: 30,000 DAI
- Init Lockstake Engine with uint256 duty: 12%
- Init Lockstake Engine with uint256 mat: 200%
- Init Lockstake Engine with uint256 buf: 1.20
- Init Lockstake Engine with uint256 tail: 6,000 seconds
- Init Lockstake Engine with uint256 cusp: 0.40
- Init Lockstake Engine with uint256 chip: 0.1%
- Init Lockstake Engine with uint256 tip: 300 DAI
- Init Lockstake Engine with uint256 stopped: 0
- Init Lockstake Engine with uint256 chop: 8%
- Init Lockstake Engine with uint256 hole: 3 million DAI
- Init Lockstake Engine with uint256 tau: 0
- Init Lockstake Engine with uint256 cut: 0.99
- Init Lockstake Engine with uint256 step: 60 seconds
- Init Lockstake Engine with bool lineMom: true
- Init Lockstake Engine with uint256 tolerance: 0.5
- Init Lockstake Engine with string name: "LockstakeMkr"
- Init Lockstake Engine with string symbol: "lsMKR"
- "Under the hood" actions for Init Lockstake Engine:
- New collateral type "LSE-MKR-A" will be added to "vat", "jug", "spotter", "dog" contracts
- New collateral type "LSE-MKR-A" will be added to LINE_MOM
- New collateral type "LSE-MKR-A" will be added to auto-line using provided maxLine, gap and ttl
- New collateral type "LSE-MKR-A" will be added to ILK_REGISTRY with provided values ("name", "symbol") and the new ilk class 7
- New MKR OSM will allow MCD_SPOT, CLIPPER_MOM, MCD_END and LockstakeClipper to access its price
- PIP_MKR will be added to OSM_MOM
- LockstakeClipper will be configured using provided values ("buf", "tail", "cusp", "chip", "tip", "stopped", "clip", "tolerance")
- StairstepExponentialDecrease calc contract will be configured using provided values ("cut", "step")
- The LsMkrUsdsFarm will be added to the LockstakeEngine as a first farm
- LockstakeEngine will be authorized to access "vat"
- LockstakeClipper will be authorized to access "vat" and LockstakeEngine
- CLIPPER_MOM, MCD_DOG and MCD_END will be authorized to access LockstakeClipper
- New chainlog keys LOCKSTAKE_MKR, LOCKSTAKE_ENGINE, LOCKSTAKE_CLIP and LOCKSTAKE_CLIP_CALC will be added
- OSM_MOM will be authorized to access the new MKR OSM
- SBE Parameter Changes
- Fund Early Bird Rewards Multisig
- Mint 27,222,832.80 SKY to 0x14D98650d46BF7679BBD05D4f615A1547C87Bf68
- Lower Deprecated RWA Debt Ceilings
- Remove RWA007-A from Debt Ceiling Instant Access Module
- Set RWA007-A Debt Ceiling to 0
- Initiate RWA007-A soft liquidation by calling
tell()
- Write-off the debt of RWA007-A and set its oracle price to 0 by calling
cull()
- Reduce RWA014-A Debt Ceiling by 1.5 billion Dai from 1.5 billion Dai to 0
- Initiate RWA014-A soft liquidation by calling
tell()
- Write-off the debt of RWA014-A and set its oracle price to 0 by calling
cull()
- Pinwheel DAO Resolution
- Approve DAO Resolution at QmYJUvw5xbAJmJknG2xUKDLe424JSTWQQhbJCnucRRjUv7
- AAVE Revenue Share Payment
- AAVE Revenue Share - 234089 DAI - 0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c
- Spark Spell
- Execute Spark Proxy Spell at 0xcc3B9e79261A7064A0f734Cc749A8e3762e0a187
- Setup new MkrOsm
- Exec Sheet for the specified date is found in the "Executive Vote Implementation Process" google sheet
-
Base checks
- Current solc version
0.8.16
- Office hours is
true
IF spell introduces a major change that can affect external parties (e.g.: keepers are affected in case of collateral offboarding) OTHERWISE explicitly set tofalse
- Office hours value matches the Exec Sheet
- 30 days spell expiry set in the constructor (
block.timestamp + 30 days
)
- Current solc version
-
Spell description
- Description follows the format
TARGET_DATE MakerDAO Executive Spell | Hash: EXEC_DOC_HASH
-
TARGET_DATE
in the description matches the target date - Accompanying comment above spell description follows the format
// Hash: cast keccak -- "$(wget 'EXEC_DOC_URL' -q -O - 2>/dev/null)"
- Description follows the format
-
Comments inside the spell
- Every Section text from the Exec Sheet is copied to the spell code as a comment surrounded by the set of dashes (E.g.
// ----- Section text -----
) - Every Instruction text from the Exec Sheet is copied to the spell code as
// Instruction text
- Every Instruction text have newline above it
- IF an instruction can not be taken, it should have explanation under the instruction prefixed with
// Note:
(e.g.:// Note: Payments are skipped on goerli
) - IF action in the spell doesn't have relevant instruction (e.g.:
chainlog
version bump), the necessity of it is explained in the comment above prefixed with// Note:
- Every proof url from the Exec Sheet, such as
Reasoning URL
andAuthority URL
is present in the spell code under relevant section or instruction (depending on which row the url is present) - Every proof url from the Exec Sheet, such as
Reasoning URL
andAuthority URL
have prefix derived from the url itself// Executive Vote:
if URL starts withhttps://vote.makerdao.com/executive/
// Poll:
if URL starts withhttps://vote.makerdao.com/polling/
// Forum:
if URL starts withhttps://forum.makerdao.com/t/
// MIP:
if URL starts withhttps://mips.makerdao.com/mips/details/
- Every Section text from the Exec Sheet is copied to the spell code as a comment surrounded by the set of dashes (E.g.
-
Dependency checks
- Update Foundry by running
foundryup
- Reinstall libraries by running
rm -rf ./lib && git submodule update --init --recursive
Submodule path 'lib/dss-exec-lib': checked out '69b658f35d8618272cd139dfc18c5713caf6b96b' Submodule path 'lib/dss-exec-lib/lib/dss-interfaces': checked out '9bfd7afadd1f8c217ef05850b2555691786286cb' Submodule path 'lib/dss-exec-lib/lib/forge-std': checked out '0aa99eb8456693c015350c5e6c4f442ebe912f77' Submodule path 'lib/dss-exec-lib/lib/forge-std/lib/ds-test': checked out 'cd98eff28324bfac652e63a239a60632a761790b' Submodule path 'lib/dss-test': checked out '36ff4adbcb35760614e0d2df864026991c23d028' Submodule path 'lib/dss-test/lib/dss-interfaces': checked out '9bfd7afadd1f8c217ef05850b2555691786286cb' Submodule path 'lib/dss-test/lib/forge-std': checked out '155d547c449afa8715f538d69454b83944117811' Submodule path 'lib/dss-test/lib/forge-std/lib/ds-test': checked out 'e282159d5170298eb2455a6c05280ab5a73a4ef0'
-
IF submodule upgrades are present, make suredss-exec-lib
is synced as well - git submodule hash of
dss-exec-lib
(rungit submodule status
) matches the latest release version or newer -
dss-interfaces
library used insidelib/dss-exec-lib
matches submodule used insidelib/dss-test
- Update Foundry by running
-
IF interfaces are present in the spell
- Interfaces imported from
dss-interfaces
- No unused
dss-interfaces
- Only single import layout is used (e.g.
import "dss-interfaces/dss/VatAbstract.sol";
)
- No unused
- Static Interfaces
- No unused static interfaces
- Declared static interface not present in the
dss-interfaces
, OTHERWISE should be imported from there - Interface matches deployed contract using
cast interface <contract_address>
command - Interface naming style should match with
Like
suffix (e.g.VatLike
)- EXCEPTION: known interface naming exceptions
- Each static interface declare only functions actually used in the spell code
- Interfaces imported from
-
IF variable declarations are present in the spell
- IF precision units are present
- Precision units used in the spell match their defined values:
WAD = 10 ** 18
RAY = 10 ** 27
RAD = 10 ** 45
- Precision units match with Numerical Ranges
- Each variable visibility is declared as
internal
- Each variable state mutability is declared as
constant
- Precision units used in the spell match their defined values:
- IF math units are present
- Match their defined values:
HUNDRED = 10 ** 2
THOUSAND = 10 ** 3
MILLION = 10 ** 6
BILLION = 10 ** 9
- Match with config
- Each variable visibility is declared as
internal
- Each variable state mutability is declared as
constant
- Match their defined values:
- IF rates are present
- Rates match generated locally via
make rates pct=<pct>
(e.g. pct=0.75, for 0.75%) - Rates match IPFS document
- Rate variable name conforms to
X_PT_Y_Z_PCT_RATE
(e.g.ZERO_PT_SEVEN_FIVE_PCT_RATE
for 0.75%) - Rate variable visibility declared as
internal
- Rate variable state mutability declared as
constant
- Rates match generated locally via
IF timestamps are present-
Comment above timestamp states full date includingUTC
timezone -
Timestamp converts back to the correct date -
Timestamp converts back to theUTC
timezone -
Variable naming matchesMMM_DD_YYYY
(e.g.JAN_01_2023
for 2023-01-01) -
Time of day makes logical sense in the context of timestamp usage (i.e.23:59:59 UTC
for the final day of something,00:00:00 UTC
for the first day of something) -
Each variable visibility is declared asinternal
-
Each variable state mutability is declared asconstant
-
- IF precision units are present
-
IF new contract is present in the spell (not yet on chainlog or new to chainlog)
NEW_PIP_MKR = 0x4F94e33D0D74CfF5Ca0D3a66F1A650628551C56b
- Source code is verified on etherscan
- Compilation optimizations match deployment settings defined in the source code repo
-
GNU AGPLv3
license - Every maker-related constructor argument matches chainlog (e.g.
vat
,dai
,dog
, ...) - IF new contract have concept of
wards
or access control- Ensure
PAUSE_PROXY
address wasrelied
(wards(PAUSE_PROXY)
is1
) - Ensure that contract deployer address was
denied
(wards(deployer)
is0
) - Ensure that there are no other
Rely
events except forPAUSE_PROXY
(using a block explorer like etherscan)
- Ensure
- Source code matches corresponding github source code (e.g. diffcheck via vscode
code --diff etherscan.sol github.sol
) - Deployer address is included into
addresses_deployers.sol
VOTE_DELEGATE_FACTORY = 0xC3D809E87A2C9da4F6d98fECea9135d834d6F5A0
- Source code is verified on etherscan
- Compilation optimizations match deployment settings defined in the source code repo
-
GNU AGPLv3
license - Every maker-related constructor argument matches chainlog (e.g.
vat
,dai
,dog
, ...)-
_chief
:0x0a3f6849f78076aefaDf113F5BED87720274dDC0
-
_polling
:0xD3A9FE267852281a1e6307a1C37CDfD76d39b133
-
-
IF new contract have concept ofwards
or access control-
EnsurePAUSE_PROXY
address wasrelied
(wards(PAUSE_PROXY)
is1
) -
Ensure that contract deployer address wasdenied
(wards(deployer)
is0
) -
Ensure that there are no otherRely
events except forPAUSE_PROXY
(using a block explorer like etherscan)
-
-
Source code matches corresponding github source code (e.g. diffcheck via vscodecode --diff etherscan.sol github.sol
) - Bytecode matches corresponding GitHub source code:
> forge verify-bytecode 0xC3D809E87A2C9da4F6d98fECea9135d834d6F5A0 VoteDelegateFactory < Verifying bytecode for contract VoteDelegateFactory at address 0xC3D809E87A2C9da4F6d98fECea9135d834d6F5A0 < Creation code matched with status full < Runtime code matched with status full
- Deployer address is included into
addresses_deployers.sol
REWARDS_LSMKR_USDS = 0x92282235a39bE957fF1f37619fD22A9aE5507CB1
- Source code is verified on etherscan
- Compilation optimizations match deployment settings defined in the source code repo
-
GNU AGPLv3
license - Every maker-related constructor argument matches chainlog (e.g.
vat
,dai
,dog
, ...)-
_owner
:0xBE8E3e3618f7474F8cB1d074A26afFef007E98FB
(MCD_PAUSE_PROXY) -
_rewardsDistribution
:0x0000000000000000000000000000000000000000
(to be initialized later) -
_rewardsToken
:0xdC035D45d973E3EC169d2276DDab16f1e407384F
(USDS) -
_stakingToken
:0xb4e0e45e142101dC3Ed768bac219fC35EDBED295
(LockstakeMkr)
-
-
IF new contract have concept ofwards
or access control-
EnsurePAUSE_PROXY
address wasrelied
(wards(PAUSE_PROXY)
is1
) -
Ensure that contract deployer address wasdenied
(wards(deployer)
is0
) -
Ensure that there are no otherRely
events except forPAUSE_PROXY
(using a block explorer like etherscan)
-
-
Source code matches corresponding github source code (e.g. diffcheck via vscodecode --diff etherscan.sol github.sol
) - Bytecode matches corresponding GitHub source code:
> forge verify-bytecode 0x92282235a39bE957fF1f37619fD22A9aE5507CB1 StakingRewards < Verifying bytecode for contract StakingRewards at address 0x92282235a39bE957fF1f37619fD22A9aE5507CB1 < Creation code matched with status full < Runtime code matched with status full
- Deployer address is included into
addresses_deployers.sol
LOCKSTAKE_MKR = 0xb4e0e45e142101dC3Ed768bac219fC35EDBED295
- Source code is verified on etherscan
- Compilation optimizations match deployment settings defined in the source code repo
-
GNU AGPLv3
license -
Every maker-related constructor argument matches chainlog (e.g.vat
,dai
,dog
, ...) - IF new contract have concept of
wards
or access control- Ensure
PAUSE_PROXY
address wasrelied
(wards(PAUSE_PROXY)
is1
) - Ensure that contract deployer address was
denied
(wards(deployer)
is0
) - Ensure that there are no other
Rely
events except forPAUSE_PROXY
(using a block explorer like etherscan)
- Ensure
-
Source code matches corresponding github source code (e.g. diffcheck via vscodecode --diff etherscan.sol github.sol
) - Bytecode matches corresponding GitHub source code:
> forge verify-bytecode 0xb4e0e45e142101dC3Ed768bac219fC35EDBED295 LockstakeMkr < Verifying bytecode for contract LockstakeMkr at address 0xb4e0e45e142101dC3Ed768bac219fC35EDBED295 < Creation code matched with status full < Runtime code matched with status full
- Deployer address is included into
addresses_deployers.sol
LOCKSTAKE_ENGINE = 0x2b16C07D5fD5cC701a0a871eae2aad6DA5fc8f12
- Source code is verified on etherscan
- Compilation optimizations match deployment settings defined in the source code repo
-
GNU AGPLv3
license - Every maker-related constructor argument matches chainlog (e.g.
vat
,dai
,dog
, ...)-
voteDelegateFactory_
:0xC3D809E87A2C9da4F6d98fECea9135d834d6F5A0
(VOTE_DELEGATE_FACTORY) -
usdsJoin_
:0x3C0f895007CA717Aa01c8693e59DF1e8C3777FEB
(USDS_JOIN) -
ilk_
:0x4c53452d4d4b522d410000000000000000000000000000000000000000000000
(LSE-MKR-A) -
mkrSky_
:0xBDcFCA946b6CDd965f99a839e4435Bcdc1bc470B
(MKR_SKY) -
lsmkr_
:0xb4e0e45e142101dC3Ed768bac219fC35EDBED295
(lsMkr)
-
- IF new contract have concept of
wards
or access control- Ensure
PAUSE_PROXY
address wasrelied
(wards(PAUSE_PROXY)
is1
) - Ensure that contract deployer address was
denied
(wards(deployer)
is0
) - Ensure that there are no other
Rely
events except forPAUSE_PROXY
(using a block explorer like etherscan)
- Ensure
-
Source code matches corresponding github source code (e.g. diffcheck via vscodecode --diff etherscan.sol github.sol
) - Bytecode matches corresponding GitHub source code:
> forge verify-bytecode 0x2b16C07D5fD5cC701a0a871eae2aad6DA5fc8f12 LockstakeEngine < Verifying bytecode for contract LockstakeEngine at address 0x2b16C07D5fD5cC701a0a871eae2aad6DA5fc8f12 < Creation code matched with status full < Runtime code matched with status full
- Deployer address is included into
addresses_deployers.sol
LOCKSTAKE_CLIP = 0xA85621D35cAf9Cf5C146D2376Ce553D7B78A6239
- Source code is verified on etherscan
- Compilation optimizations match deployment settings defined in the source code repo
-
GNU AGPLv3
license - Every maker-related constructor argument matches chainlog (e.g.
vat
,dai
,dog
, ...)-
vat_
:0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B
(MCD_VAT) -
spotter_
:0x65C79fcB50Ca1594B025960e539eD7A9a6D434A3
(MCD_SPOT) -
dog_
:0x135954d155898D42C90D2a57824C690e0c7BEf1B
(MCD_DOG) -
engine_
:0x2b16C07D5fD5cC701a0a871eae2aad6DA5fc8f12
(LockstakeEngine)
-
- IF new contract have concept of
wards
or access control- Ensure
PAUSE_PROXY
address wasrelied
(wards(PAUSE_PROXY)
is1
) - Ensure that contract deployer address was
denied
(wards(deployer)
is0
) - Ensure that there are no other
Rely
events except forPAUSE_PROXY
(using a block explorer like etherscan)
- Ensure
-
Source code matches corresponding github source code (e.g. diffcheck via vscodecode --diff etherscan.sol github.sol
) - Bytecode matches corresponding GitHub source code:
> forge verify-bytecode 0xA85621D35cAf9Cf5C146D2376Ce553D7B78A6239 LockstakeClipper < Verifying bytecode for contract LockstakeClipper at address 0xA85621D35cAf9Cf5C146D2376Ce553D7B78A6239 < Creation code matched with status full < Runtime code matched with status full
- Deployer address is included into
addresses_deployers.sol
LOCKSTAKE_CLIP_CALC = 0xf13cF3b39823CcfaE6C2354dA56416C80768474e
- Source code is verified on etherscan
- Compilation optimizations match deployment settings defined in the source code repo
-
GNU AGPLv3
license -
Every maker-related constructor argument matches chainlog (e.g.vat
,dai
,dog
, ...) - IF new contract have concept of
wards
or access control- Ensure
PAUSE_PROXY
address wasrelied
(wards(PAUSE_PROXY)
is1
) - Ensure that contract deployer address was
denied
(wards(deployer)
is0
) - Ensure that there are no other
Rely
events except forPAUSE_PROXY
(using a block explorer like etherscan)
- Ensure
-
Source code matches corresponding github source code (e.g. diffcheck via vscodecode --diff etherscan.sol github.sol
) - Bytecode matches on-chain MCD_CLIP_CALC_MATIC_A
-
Deployer address is included intoaddresses_deployers.sol
- Deployed through
CALC_FAB
on-chain factory
-
IF core system parameter changes are present in the instructions
IF stability fee (jug.ilk.duty
) is updated-
(DssExecLib.setIlkStabilityFee(ilk, rate, doDrip)
) is used -
Comment matches pattern// Increase ILK-A Stability Fee by X.XX% from X.XX% to X.XX%
-
IF Dai Savings Rate (pot.dsr
) is updated-
(DssExecLib.setDSR(rate, doDrip)
) is used -
Comment matches pattern// Increase DSR by X.XX% from X.XX% to X.XX%
-
Double check that rate matchmake rates pct=<pct>
(e.g. pct=0.75, for 0.75%) -
Double check that rate match IPFS document
-
-
IFspotter.ilk.mat
is updated, (DssExecLib.setIlkLiquidationRatio(ilk, pct_bps)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFdog.ilk.hole
is updated, (DssExecLib.setIlkMaxLiquidationAmount(ilk, amount)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFvat.ilk.dust
is updated, (DssExecLib.setIlkMinVaultAmount(ilk, amount)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFdog.ilk.chop
is updated, (DssExecLib.setIlkLiquidationPenalty(ilk, pct_bps)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFclip.buf
is updated, (DssExecLib.setStartingPriceMultiplicativeFactor(ilk, pct_bps)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFclipperMom.clip.tolerance
is updated, (DssExecLib.setLiquidationBreakerPriceTolerance(clip, pct_bps)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFclip.tail
is updated, (DssExecLib.setAuctionTimeBeforeReset(ilk, duration)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFclip.cusp
is updated, (DssExecLib.setAuctionPermittedDrop(ilk, pct_bps)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFclip.chip
is updated, (DssExecLib.setKeeperIncentivePercent(ilk, pct_bps)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFclip.tip
is updated, (DssExecLib.setKeeperIncentiveFlatRate(ilk, amount)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFcalc.tau
is updated, (DssExecLib.setLinearDecrease(calc, duration)
) is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IFcalc.cut
orcalc.step
are updated,DssExecLib.setStairstepExponentialDecrease(calc, duration, pct_bps)
is used⚠️ updated withinLockstakeInit.init()
using low-level methods
-
IF debt ceiling changes are present in the instructions
- IF adjusted collateral type (
ilk
) have AutoLine enabled (MCD_IAM_AUTO_LINE
)- IF collateral debt ceiling requested to be
0
- Collateral is removed from AutoLine (
MCD_IAM_AUTO_LINE
) viaDssExecLib.removeIlkFromAutoLine(ilk)
- The instruction to remove from AutoLine (
MCD_IAM_AUTO_LINE
) is present in the Exec Sheet - Collateral debt ceiling is set to
0
viaDssExecLib.setIlkDebtCeiling(ilk, amount)
- Global debt ceiling (
vat.Line
) is updated accordingly, UNLESS specifically instructed not to
- Collateral is removed from AutoLine (
IFAutoLine
parameters are updated-
EITHER is used, depending on the instruction: ⚠️ updated withinLockstakeInit.init()
using low-level methods
-
- IF collateral debt ceiling requested to be
IF collateral debt ceiling (vat.ilk.line
) is updated-
Collateral type (ilk
) haveAutoLine
disabled previously or in the spell -
EITHER is used, depending on the instruction: - Global debt ceiling (
vat.Line
) is updated accordingly, UNLESS specifically instructed not to, via EITHER:global
set totrue
inincreaseIlkDebtCeiling
/decreaseIlkDebtCeiling
DssExecLib.setGlobalDebtCeiling(amount)
DssExecLib.increaseGlobalDebtCeiling(amount)
DssExecLib.decreaseGlobalDebtCeiling(amount)
-
- IF adjusted collateral type (
-
IF additional dependencies (i.e.
./src/dependencies/
directory) are present:- IF the dependencies contracts/libraries have been audited
- Each contract/library exactly matches (i.e. diff check) the source code of the latest audited version
dss-flappers
:- Audit report: https://github.com/makerdao/dss-flappers/blob/e136bb19e6176762b63b26314c7ae6339f6a96b5/audit/20240904-ChainSecurity_MakerDAO_Dss_Flappers_audit.pdf
- Latest commit:
95431f3d4da66babf81c6e1138bd05f5ddc5e516
- Repo files:
deploy/FlapperInit.sol
deploy/SplitterInstance.sol
- Spell files matching repo:
-
src/dependencies/dss-flappers/FlapperInit.sol
-
src/dependencies/dss-flappers/SplitterInstance.sol
-
lockstake
:- Audit report: https://github.com/makerdao/lockstake/blob/445cd304bab69ff79c15ab947cb48bbe8aadf400/audit/20240909-ChainSecurity_MakerDAO_Lockstake_audit.pdf
- Latest commit:
7c71318623f5d6732457fd0c247a1f1760960011
- Repo files:
deploy/LockstakeInit.sol
deploy/LockstakeInstance.sol
- Spell files matching repo:
-
src/dependencies/lockstake/LockstakeInit.sol
-
src/dependencies/lockstake/LockstakeInstance.sol
-
- Each contract/library exactly matches (i.e. diff check) the source code of the latest audited version
-
OTHERWISE obtain the permalink to the relevant repository from a trusted party (i.e. Gov Facilitators)-
Each contract/library exactly matches (i.e. diff check) the source code from the permalink
-
- IF the dependencies contracts/libraries have been audited
-
IF onboarding is present
- Insert and follow the relevant checklists below:
- Collateral Onboarding
- Deployed Contracts
-
PIP
(Oracle)- deployed via deployer (OSM)
- contract is verified on etherscan
- ensure solc version matches source
- ensure optimization matches source configs
- ensure license
AGPLv3
is specified - ensure source matches github code (i.e. diffcheck via vscode
code --diff etherscan.sol github.sol
)- Manual diff: https://www.diffchecker.com/zxVqxRsH/
⚠️ small changes are present, mostly comments and changes required by the compiler.
- Manual diff: https://www.diffchecker.com/zxVqxRsH/
- constructor args are correct
-
src
(medianizer) - check
wards
-
MCD_PAUSE_PROXY
is relied - deployer is denied
- no other address has been relied
-
deployed via Factory (LPs)-
Fab matches -
univ2-lp-oracle -
univ3-lp-oracle -
curve-lp-oracle
-
- deployed via deployer (OSM)
-
Join
(Join Adapter)-
deployed via JoinFab-
Fab matches chainlog -
newGemJoin
(Standard ERC-20 Join Adapter) -
newGemJoin5
(Custom Adapter for Tokens with lower precision than 18) -
AuthGemJoin
(Custom Adapter for Tokens that needs authedjoin
access) -
parameters are correct -
owner
matches MCD Pause Proxy -
ilk
is thebytes32
representation of "TOKEN-A"-
cast --to-ascii <bytes32>
matches ASCII Ilk -
cast --to-bytes32 $(cast --from-ascii "TOKEN-A")
matchesbytes32
-
-
gem
matches token contract
-
-
-
Clip
-
deployed via ClipFab-
Fab matches chainlog -
newClip
parameters are correct -
owner
matches MCD Pause Proxy -
vat
matches chainlog -
spotter
matches chainlog -
dog
matches chainlog -
ilk
is thebytes32
representation of "TOKEN-A"-
cast --to-ascii <bytes32>
matches ASCII Ilk -
cast --to-bytes32 $(cast --from-ascii "TOKEN-A")
matchesbytes32
-
-
⚠️ Deployment validated above
-
-
Calc
- deployed via CalcFab
- Fab matches chainlog
-
newStairstepExponentialDecrease
-
newLinearDecrease
-
newExponentialDecrease
- parameters are correct
-
owner
matches MCD Pause Proxy
- Risk Parameters
-
vat.ilk.line
(setIlkDebtCeiling) -
dog.ilk.hole
(setIlkMaxLiquidationAmount) -
vat.ilk.dust
(setIlkMinVaultAmount) -
dog.ilk.chop
(liquidationPenalty) -
jug.ilk.duty
(setIlkStabilityFee) -
spotter.ilk.mat
(liquidationRatio) -
clip.buf
(startingPriceFactor) -
clipperMom.clip.tolerance
(setLiquidationBreakerPriceTolerance) -
clip.tail
(auctionDuration) -
clip.cusp
(permittedDrop) -
clip.chip
(kprPctReward) -
clip.tip
(kprFlatReward) -
abaci
-
LinearDecrease-
calc.tau
(setLinearDecrease)
-
-
StairstepExponentialDecrease - setStairstepExponentialDecrease
-
calc.cut
-
calc.step
-
-
-
- Autoline (setIlkAutoLineParameters)
-
ilk
-
line
-
gap
-
ttl
-
- Onboarding Actions
-
ensureDssExecLib.addNewCollateral
is used
⚠️ done withinLockstakeInit.init()
using low-level methods -
ensureCollateralOpts
is used-
ilk
follows the ilk formatTOKEN-A
-
gem
matches token address -
join
matches token join address -
clip
matches token clip address -
calc
matches token calc address -
pip
matches token pip address -
isLiquidatable
set to true if liquidations are on -
isOSM
set to true IFpip
isOSM
-
whitelistOSM
set to true IF median issrc
inOSM
-
ilkDebtCeiling
(vat.ilk.line
) in DAI (e.g. 1 * MILLION) -
IF autoline is enabled,vat.ilk.line
should be set to DC-IAMgap
value -
minVaultAmount
(vat.ilk.dust
) in DAI (e.g. 15_000) -
ensureclip.tip
is adjusted proportionally tovat.ilk.dust
(e.g. lower thedust
lower thetip
) -
maxLiquidationAmount
(dog.ilk.hole
) in DAI (e.g. 5 * MILLION) -
ensuredog.ilk.hole
>=ilk.dust
invariant holds -
liquidationPenalty
(dog.ilk.chop
) in basis points (e.g. 13% = 13_00) -
ilkStabilityFee
(jug.ilk.duty
) set via script or IPFS rates table (e.g. 1000000000031693947650284507) -
startingPriceFactor
(clip.buf
) in basis points (e.g. 110% = 110_00) -
breakerTolerance
(clipperMom.clip.tolerance
) in basis points (e.g. 50% = 50_00) -
auctionDuration
(clip.tail
) in seconds (e.g. 220 minutes) -
permittedDrop
(clip.cusp
) in basis points (e.g. 45% = 45_00) -
liquidationRatio
(spotter.ilk.mat
) in basis points (e.g. 170% = 170_00) -
kprFlatReward
(clip.tip
) in DAI (e.g. 250) -
kprPctReward
(clip.chip
) in basis points (e.g. 0.1% = 10)
-
-
set Calc parameters-
LinearDecrease
-
calc.tau
in seconds (e.g. 250 days = 21_600_000) -
StairstepExponentialDecrease
-
calc.step
in seconds (e.g. 120 seconds) -
calc.cut
in basis points (e.g. 99% = 99_00)
-
- set Ilk Autoline Parameters (IF Autoline is enabled)
-
ilk
follows the ilk formatTOKEN-A
-
line
in DAI (e.g. 10 * MILLION) -
gap
in DAI (e.g. 1 * MILLION) -
ttl
in seconds (e.g. 8 hours)
-
-
- New Chainlog Entries
-
LOCKSTAKE_MKR
-
LOCKSTAKE_ENGINE
-
LOCKSTAKE_CLIP
-
LOCKSTAKE_CLIP_CALC
-
- Chainlog Bump
- Patch
x.x.1
- Patch
- Test Coverage (Follow Previous Test Patterns)
-
testCollateralIntegrations
-
testNewChainlogValues
-
testNewIlkRegistryValues
- ensure new chainlog entries are included in
addresses_<mainnet, goerli>.sol
- ensure deployer addresses are included into
addresses_deployers.sol
(to keep up to date) -
config.sol
-
-
- Deployed Contracts
RWA OnboardingTeleport Onboarding
- Collateral Onboarding
- Insert and follow the relevant checklists below:
-
IF PSM migration, onboarding or offboarding is present:-
Insert and follow the relevant checklists below:
-
-
IF D3M onboarding is present, insert and follow D3M Checklist -
IF collateral offboarding is present in the spell
- 1st stage collateral offboarding
- RWA007-A:
- Collateral type (
ilk
) is removed from AutoLine (MCD_IAM_AUTO_LINE
) IF currently enabled - Collateral debt ceiling (
vat.ilk.line
) is set to0
- Global debt ceiling (
vat.Line
) decreased by the total amount of offboarded ilks
- Collateral type (
- RWA014-A:
-
Collateral type (ilk
) is removed from AutoLine (MCD_IAM_AUTO_LINE
) IF currently enabled - Collateral debt ceiling (
vat.ilk.line
) is set to0
- Global debt ceiling (
vat.Line
) decreased by the total amount of offboarded ilks
-
- RWA007-A:
- 2nd stage collateral offboarding
-
All actions from the 1st stage offboarding are previously taken (EITHER in the current or past spells – check the archive) -
Collateral liquidation penalty (chop
) is set to0
IF requested by governance -
Flat keeper incentive (tip
) is set to0
IF requested by governance -
Relative keeper incentive (chip
) is set to0
IF requested by governance -
Max liquidation amount (hole
) is adjusted viaDssExecLib.setIlkMaxLiquidationAmount(ilk, amount)
IF requested by governance -
Relevant clipper contract (MCD_CLIP_
) is active (i.e.stopped
is0
) -
Liquidations are triggered via (depending on governance instruction):EITHER liquidation ratio (spotter.ilk.mat
) being set very high in the spell (usingDssExecLib.setValue(DssExecLib.spotter(), ilk, "mat", ratio)
)OR via enabling linear interpolation (DssExecLib.linearInterpolation(name, target, ilk, what, startTime, start, end, duration)
)-
Ensurename
format matches "XXX-X Offboarding" -
Ensuretarget
matchesDssExecLib.spotter()
address -
Ensureilk
format matches collateral type (ilk
) name ("XXX-X"
) -
Ensurewhat
matches string"mat"
-
EnsurestartTime
matchesblock.timestamp
-
Ensurestart
uses variableCURRENT_XXX_A_MAT
-
Ensurestart
matches currentspotter.ilk.mat
value -
Ensureend
uses variableTARGET_XXX_A_MAT
-
Ensureend
value matches the instruction -
Ensureend
allows liquidation of all remaining vaults (end
is bigger thancollateral_type_collateralization_ratio * risk_multiplier_factor
) -
Ensureduration
matches the instruction
-
- Spotter price is updated via
DssExecLib.updateCollateralPrice(ilk)
IF collateral have no running oracle (i.e. relevantPIP_
contract have outdatedzzz
value)- RWA007-A
- RWA014-A
- Spotter price is updated after all other actions
- RWA007-A
- RWA014-A
-
Offboarding is tested at least via_checkIlkClipper
helper
-
- 1st stage collateral offboarding
-
IF RWA updates are presentIFdoc
is updated-
_updateDoc
helper is copied one-to-one from the archive and defined aboveactions
-
_updateDoc(ilk, doc)
is called in the spell
-
IF debt ceiling is updatedIF AutoLine update is requested by the Exec Sheet-
Parameters are set viaDssExecLib.setIlkAutoLineParameters(ilk, amount, gap, ttl)
orDssExecLib.setIlkAutoLineDebtCeiling(ilk, amount)
-
IF regular debt ceiling (vat.ilk.line
) update is requested by the Exec Sheet-
Collateral type (ilk
) haveAutoLine
disabled previously or in the spell -
Debt ceiling (vat.ilk.line
) is updated, via EITHER: -
Global debt ceiling (vat.Line
) is updated accordingly, UNLESS specifically instructed not to, via EITHER:global
set totrue
inincreaseIlkDebtCeiling
/decreaseIlkDebtCeiling
DssExecLib.setGlobalDebtCeiling(amount)
DssExecLib.increaseGlobalDebtCeiling(amount)
DssExecLib.decreaseGlobalDebtCeiling(amount)
-
-
Liquidation oracle price is bumped viaRwaLiquidationOracleLike(MIP21_LIQUIDATION_ORACLE).bump(ilk, val)
pattern-
Comment abovebump
explainsval
computation via// Note: the formula is: "debt_ceiling * [ (1 + rwa_stability_fee ) ^ (minimum_deal_duration_in_years) ] * liquidation_ratio"
-
Comment abovebump
provides locally executable formula (e.g.// bc -l <<< 'scale=18; 50000000 * e(l(1.07) * (3342/365)) * 1.00' | cast --to-wei
)-
The formula matches the example provided above -
debt_ceiling
in the executable formula matches new debt ceiling set in the spell or the maximum possible debt ceiling in case of the enabled AutoLine -
rwa_stability_fee
in the executable formula matches stability fee of the specified RWA found on chain -
minimum_deal_duration_in_years
in the executable formula matches number found in the Exec Sheet of the spell containing relevant RWA onboarding -
liquidation_ratio
in the executable formula matches liquidation ratio of the specified RWA found on chain -
Executing formula locally provides integer number that matches theval
in the spell
-
-
val
makes sense in context of the rate mechanism
-
-
IF multiple RWA ilks are being combined into one,val
calculation is done once per ilk and added to make the total, with separate executable formulas provided in comments. The existingval
value can be retrieved by callingread()
onPIP_RWAXX
and converting the result into decimal -
Oracle price is updated viaDssExecLib.updateCollateralPrice(ilk)
- IF soft liquidation explicitly requested to be triggered (via
.tell(ilk)
) AND debt ceiling is0
(OR is being set to0
in the current spell)-
RwaLiquidationOracle.tell(ilk)
call is present- RWA007-A
- RWA014-A
-
IFRWAXX_A_INPUT_CONDUIT
is an instance ofTinlakeMgr
(it is a Centrifuge integration), additionalTinlakeMgr.tell()
call is present (in order to prevent furtherTIN
redemptions in the Centrifuge pool)
-
-
IF payments are present in the spell
IFMKR
transfers are present-
Recipient address in the instruction is in the checksummed format -
Recipient address matches Exec Sheet -
Recipient address variable name matches one found inaddresses_wallets.sol
-
Transfer amount matches Exec Sheet -
Transfer amount is specified with (at least) 2 decimals usingether
keyword -
IFether
keyword is used, comment is present on the same line// Note: ether is a keyword helper, only MKR is transferred here
-
The transfers are tested viatestMKRPayments
test -
Sum of all MKR transfers tested intestMKRPayments
matches number in the Exec Sheet
-
- IF
DAI
surplus buffer transfers are present- Recipient address in the instruction is in the checksummed format
- Recipient address matches Exec Sheet
- Recipient address variable name matches one found in
addresses_wallets.sol
- Transfer amount matches Exec Sheet
- The transfers are tested via
testDAIPayments
test
⚠️ testDAIPayments
was refactored into a generaltestPayments
test case, aiming to test payments from all native tokens in the Sky Protocol (Dai, MKR, USDS and SKY) - Sum of all DAI transfers tested in
testDAIPayments
matches number in the Exec Sheet
IFMKR
orDAI
streams (DssVest
) are created-
VestAbstract
interface is imported fromdss-interfaces/dss/VestAbstract.sol
-
restrict
is used for each stream, UNLESS otherwise explicitly stated in the Exec Sheet -
usr
(Vest recipient address) matches Exec Sheet -
usr
address in the instruction is in the checksummed format -
usr
address variable name match one found inaddresses_wallets.sol
-
tot
(Total stream amount) matches Exec Sheet -
IFether
keyword is used, comment is present on the same line// Note: ether is a keyword helper, only MKR is transferred here
-
IF vest amount is expressed in 'per year' or similar in the Exec Sheet, account for leap days -
bgn
(Vest start timestamp) matches Exec Sheet -
tau
is expressed asbgn - fin
(i.e.MONTH_DD_YYYY - MONTH_DD_YYYY
) -
fin
(Vest end timestamp) matches Exec Sheet -
eta
(Vest cliff duration) matches the following logicIFeta
is explicitly specified in the Exec Sheet, then the values matchIFeta
andclf
(Cliff end timestamp) are not specified in the Exec Sheet, theneta
is0
IFclf
is specified, butclf <= bgn
, theneta
is0
IFclf
is specified andclf > bgn
,eta
is expressed asclf - bgn
(i.e.MONTH_DD_YYYY - MONTH_DD_YYYY
)
-
IFmgr
(Vest manager address) is specified in the Exec Sheet, matches the value, OTHERWISE matchesaddress(0)
-
Ensure that max vesting rate (cap
) is enough for the new streamsThe maximum vesting rate (tot
divided bytau
)<=
the maximum vest streaming rate (cap
)The maximum vesting rate (tot
divided bytau
)>
the maximum vest streaming rate (cap
)Calculate newcap
value equal to 10% greater than the new maximum vesting rate, then round newcap
up with 2 significant figure precision (i.e. 2446 becomes 2500)
IF max vesting rate (cap
) is changed in the spell-
Governance facilitators were notified -
Exec Sheet contain explicit instruction -
Exec Sheet contain explicit instruction
-
IF MKR stream (DssVestTransferrable) is present-
Vest contract's MKR allowance increased by the cumulativetotal
(the sum of alltot
values) -
Ensure allowance increase follows archive patterns
-
-
Tested viatestVestDAI
ortestVestMKR
-
IFMKR
orDAI
vest termination (Yank
) is present-
Yanked stream ID matches Exec Sheet -
MCD_VEST_MKR_TREASURY
chainlog address is used for MKR streamyank
-
MCD_VEST_DAI
chainlog address is used for DAI streamyank
-
Tested viatestYankDAI
ortestYankMKR
-
-
IF SubDAO-related content is present
- IF SubDAO provides SubProxy spell address
- SubDAO spell address matches Exec Sheet
- Executed via
ProxyLike(SUBDAO_PROXY).exec(SUBDAO_SPELL, abi.encodeWithSignature("execute()"));
- Execution is NOT delegate call
- IF SubDAO spell deployer is a smart contract (e.g. multisig or factory), ensure the deployer address is in
addresses_deployers.sol
as an entry
⚠️ Deployer0x22Ab30978E37f933d4E4fEcC85C0f404C46a8314
is not inaddresses_deployers.sol
, however I consider this as non-blocking. - Ensure that SubDAO spell have enough gas and does not revert with "out of gas" error inside simulation. Note: low level call gas estimation is not done by our scripts
IF SubDAO provides instructions to be executed by the main spell (i.e. that will operate within Pause ProxyDelegateCall
context)-
No SubDAO contract being interacted with is authed on a core contract likevat
, etc. (Check comprehensively where the risk is high) -
SubDAO contract licensing and optimizations generally do not matter (except where they pose a security risk) -
SubDAO contracts and all libraries / dependencies have verified source code (Blocking)
Upgradable SubDAO contracts-
Upgradable contracts have thePAUSE_PROXY
as theiradmin
(i.e. the party that can upgrade) -
Any upgradable SubDAO contracts with anadmin
that is notPAUSE_PROXY
are not authed on any core contracts (Blocking)
-
-
All SubDAO content addresses (i.e. provided contract addresses or EOAs) present in the Maker Core spell are present in the Exec Sheet and are correct. SubDAO addresses being authed or given any permissions MUST be in the Exec Sheet. SubDAO addresses being called must be confirmed by the SubDAO spell team. -
IF addresses not PR'ed in by the SubDAO team (use git blame for example), SubDAO content addresses all have inline comment for provenance or source being OKed by SubDAO -
SubDAO actions match Exec Sheet (only where inline with main spell code) and do not affect core contracts -
Core contract knock-on actions (such as offboarding or setting DC to 0) are present in the exec and match the code -
External calls for SubDAO content are NOT delegate call -
Code does not have untoward behavior within the scope of Maker Core Contracts (e.g. up to the SubDAO proxy)
-
- IF SubDAO provides SubProxy spell address
-
IF external contracts calls are present (Not SubDAOs, e.g. Starknet)-
Target Contract doesn't block spell execution -
External call is NOTdelegatecall
-
Target Contract doesn't have permissions on the Vat -
Target Contract doesn't do anything untoward (e.g. interacting with unsafe contracts) -
Contracts deployed viaCREATE2
(e.g. if it looks like a vanity address) do not haveselfdestruct
in their code -
MCD Pause Proxy doesn't give any approvals -
All possible actions of the Target Contract are documented -
Target contract is not upgradable -
Target Contract is included in the ChainLog -
Test Coverage is comprehensive
-
-
IF spell interacts with ChainLog
- ChainLog version is incremented based on update type
- Major -> New Vat (++.0.0)
- Minor -> Core Module (DSS) Update (e.g. Flapper) (0.++.0)
- Patch -> Collateral addition or addition/modification (0.0.++)
- New addresses are added to the
addresses_mainnet.sol
- Changes are tested via
testChainlogIntegrity
andtestChainlogValues
- ChainLog version is incremented based on update type
-
Ensure every spell variable is declared as
public
/internal
-
Ensure
immutable
visibility is only used when fetching addresses from theChainLog
viaDssExecLib.getChangelogAddress(key)
andconstant
is used instead for static addresses- Fetch addresses as type
address
and wrap withLike
suffix interfaces inline (when making calls), UNLESS archive patterns permit otherwise (Such asMKR
) - Use the DssExecLib Core Address Helpers where possible (e.g.
DssExecLib.vat()
) - Where addresses are fetched from the
ChainLog
, the variable name must match the value of the ChainLog key for that address (e.g.MCD_VAT
rather thanvat
), except where the archive pattern differs from this pattern (e.g. MKR)
- Fetch addresses as type
-
Tests
- Ensure that the
DssExecLib.address
file is not being modified by the spell PR - Check all CI tests are passing as at the latest commit
95c68b5bad2faa03900bd8c973436bf6584fc880
- Ensure every test function is declared as
public
- IF the test needs to run, it MUST NOT have the
skipped
modifier; OTHERWISE, it MUST have theskipped
modifier
- IF the test needs to run, it MUST NOT have the
- Ensure each spell action has sufficient test coverage
- Setup new MkrOsm
- Whitelist MkrOsm to read from current PIP_MKR using
DssExecLib.addReaderToWhitelist
with the following parameters:
✅testOsmReaders
,testMedianReaders
- Set MkrOsm as "PIP_MKR" in the chainlog using the following parameters:
✅testChainlogIntegrity
,testChainlogValues
- Whitelist MkrOsm to read from current PIP_MKR using
- Setup new VoteDelegateFactory
- Rename "VOTE_DELEGATE_PROXY_FACTORY" to "VOTE_DELEGATE_FACTORY_LEGACY" in chainlog:
- Call CHAINLOG.removeAddress with the following parameters:
✅testChainlogIntegrity
,testRemoveChainlogValues
- Call CHAINLOG.removeAddress with the following parameters:
- Set "VOTE_DELEGATE_FACTORY" in the chainlog to 0xC3D809E87A2C9da4F6d98fECea9135d834d6F5A0
✅testChainlogIntegrity
,testChainlogValues
- Rename "VOTE_DELEGATE_PROXY_FACTORY" to "VOTE_DELEGATE_FACTORY_LEGACY" in chainlog:
- Setup Lockstake Engine
- SBE Parameter Changes
✅testGeneral
- Set Flapper farm by calling FlapperInit.setFarm with the following parameters:
✅testGeneral
- Init Lockstake Engine by calling LockstakeInit.initLockstake with the following parameters:
✅testLockstakeIlkIntegration
- SBE Parameter Changes
- Fund Early Bird Rewards Multisig
- Mint 27,222,832.80 SKY to 0x14D98650d46BF7679BBD05D4f615A1547C87Bf68
✅testPayments
- Mint 27,222,832.80 SKY to 0x14D98650d46BF7679BBD05D4f615A1547C87Bf68
- Lower Deprecated RWA Debt Ceilings
- Remove RWA007-A from Debt Ceiling Instant Access Module
✅testGeneral
- Set RWA007-A Debt Ceiling to 0
✅testGeneral
- Initiate RWA007-A soft liquidation by calling
tell()
✅testRwaTellAndCull
- Write-off the debt of RWA007-A and set its oracle price to 0 by calling
cull()
✅testRwaTellAndCull
- Reduce RWA014-A Debt Ceiling by 1.5 billion Dai from 1.5 billion Dai to 0
✅testGeneral
- Initiate RWA014-A soft liquidation by calling
tell()
✅testRwaTellAndCull
- Write-off the debt of RWA014-A and set its oracle price to 0 by calling
cull()
✅testRwaTellAndCull
- Remove RWA007-A from Debt Ceiling Instant Access Module
- Pinwheel DAO Resolution
- Approve DAO Resolution at QmYJUvw5xbAJmJknG2xUKDLe424JSTWQQhbJCnucRRjUv7
✅testDaoResolutions
- Approve DAO Resolution at QmYJUvw5xbAJmJknG2xUKDLe424JSTWQQhbJCnucRRjUv7
- AAVE Revenue Share Payment
- AAVE Revenue Share - 234089 DAI - 0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c
✅testPayments
- AAVE Revenue Share - 234089 DAI - 0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c
- Spark Spell
- Execute Spark Proxy Spell at 0xcc3B9e79261A7064A0f734Cc749A8e3762e0a187
✅testSparkSpellIsExecuted
- Execute Spark Proxy Spell at 0xcc3B9e79261A7064A0f734Cc749A8e3762e0a187
- Setup new MkrOsm
- Ensure that any other env variable does not affect execution of the tests (for example, by inspecting the output of
printenv | grep "FOUNDRY_\|DAPP_"
) - Check all tests are passing locally using
make test
- Ensure every test listed in the coverage item above is present in the logs and with the
[PASS]
prefix.
- Ensure every test listed in the coverage item above is present in the logs and with the
- Ensure that the
Using DssExecLib at: 0x8De6DDbCd5053d32292AAA0D2105A32d108484a6
[⠊] Compiling...
[⠊] Compiling 5 files with Solc 0.8.16
[⠒] Solc 0.8.16 finished in 14.88s
Compiler run successful!
Ran 2 tests for src/test/starknet.t.sol:StarknetTests
[PASS] testStarknet() (gas: 6497815)
[PASS] testStarknetSpell() (gas: 2287)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 62.60s (56.69s CPU time)
Warning: the following cheatcode(s) are deprecated and will be removed in future versions:
snapshot(): replaced by `snapshotState`
revertTo(uint256): replaced by `revertToState`
Ran 40 tests for src/DssSpell.t.sol:DssSpellTest
[SKIP] testBytecodeMatches() (gas: 0)
[PASS] testCastCost() (gas: 6375050)
[PASS] testCastOnTime() (gas: 6372079)
[PASS] testChainlogIntegrity() (gas: 11434750)
[PASS] testChainlogValues() (gas: 13836007)
[SKIP] testCollateralIntegrations() (gas: 0)
[PASS] testContractSize() (gas: 10864)
[PASS] testDaoResolutions() (gas: 11413)
[PASS] testDeployCost() (gas: 4473236)
[SKIP] testEsmAuth() (gas: 0)
[PASS] testGeneral() (gas: 31797899)
[SKIP] testIlkClipper() (gas: 0)
[SKIP] testL2ArbitrumSpell() (gas: 0)
[SKIP] testL2OptimismSpell() (gas: 0)
[SKIP] testLerpSurplusBuffer() (gas: 0)
[PASS] testLitePSMs() (gas: 7191722)
[PASS] testLockstakeIlkIntegration() (gas: 15129629)
[PASS] testMedianReaders() (gas: 6380505)
[PASS] testNewAuthorizations() (gas: 6552167)
[SKIP] testNewCronJobs() (gas: 0)
[PASS] testNewOsmMomAddition() (gas: 6418875)
[PASS] testNextCastTime() (gas: 405635)
[SKIP] testOffboardings() (gas: 0)
[PASS] testOfficeHours() (gas: 479554)
[SKIP] testOracleList() (gas: 0)
[PASS] testOsmReaders() (gas: 6396102)
[PASS] testPSMs() (gas: 7532554)
[PASS] testPayments() (gas: 6492324)
[PASS] testRemoveChainlogValues() (gas: 6378617)
[PASS] testRevertIfNotScheduled() (gas: 16830)
[PASS] testRwaTellAndCull() (gas: 6459681)
[PASS] testSparkSpellIsExecuted() (gas: 6376733)
[PASS] testSplitter() (gas: 6878708)
[PASS] testSystemTokens() (gas: 7201276)
[PASS] testUseEta() (gas: 341990)
[SKIP] testVestDAI() (gas: 0)
[SKIP] testVestMKR() (gas: 0)
[SKIP] testVestSKY() (gas: 0)
[SKIP] testYankDAI() (gas: 0)
[SKIP] testYankMKR() (gas: 0)
Suite result: ok. 25 passed; 0 failed; 15 skipped; finished in 420.52s (1410.65s CPU time)
Ran 2 test suites in 421.10s (483.11s CPU time): 27 tests passed, 0 failed, 15 skipped (42 total tests)
Pre-Deployment Stage
- Wait till the Exec Doc is merged
- Exec Doc checks
- Exec Doc for the specified date is found in the
makerdao/community
GitHub repo - Exec Doc file name follows the format
Executive vote - Month DD, YYYY.md
- Extract permanent URL to the raw markdown file and paste it below
⚠️ Updated the URL below after posting the review.
https://github.com/makerdao/community/blob/bcb5c78e658a6d886859272e8119c05708afc50e/governance/votes/Executive%20vote%20-%20October%2017,%202024.md
https://github.com/makerdao/community/blob/7c7d7d16734407fdde827801ab4bbd6878560375/governance/votes/Executive%20vote%20-%20October%2017,%202024.md - Ensure the URL uses commit hash that introduced last change to the Exec Doc, NOT merge commit
- IF there is no local copy of
makerdao/community
GitHub repo), run:git clone https://github.com/makerdao/community
-
OTHERWISE, ensure it is pointing to the latest commit on master:git switch master && git pull origin master
- Get the latest commit hash for the exec doc:
✅
git log --pretty=oneline -1 -- "<LOCAL_PATH_TO_EXEC_DOC>"
7c7d7d16734407fdde827801ab4bbd6878560375
- IF there is no local copy of
- Using Exec Doc URL from the above and the
TARGET_DATE
, generate Exec Doc Hash viamake exec-hash date=$TARGET_DATE $URL
Community repo commit: 7c7d7d16734407fdde827801ab4bbd6878560375 Raw GitHub URL: https://raw.githubusercontent.com/makerdao/community/7c7d7d16734407fdde827801ab4bbd6878560375/governance/votes/Executive%20vote%20-%20October%2017,%202024.md Exec copy hash: 0xa1e0345f807a0333170271e69caca6d384b3a715ccad597b8ad9502963eabd6f
- Using Exec Doc URL from the above, generate Exec Doc Hash via
cast keccak -- "$(curl "$URL" -o - 2>/dev/null)"
✅0xa1e0345f807a0333170271e69caca6d384b3a715ccad597b8ad9502963eabd6f
- Make sure that hash above doesn't match
keccak
hash of the empty string (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
) - Using Exec Doc URL from the above, read spell instructions from the Exec Doc and list them below
- The Seal Engine will be initialized. This requires a number of sub-actions:
- Activate a new MKROSM.
- Activate a new VoteDelegateFactory contract.
- Initialize the Seal Engine farm in the Flapper.
- Update Smart Burn Engine parameters.
- Initialize the Seal Engine and borrowing facility.
- The Multisig responsible for distributing Early Bird Rewards will be funded with newly minted SKY tokens.
- Debt Ceilings for the now defunct RWA vaults operated by Monetalis will be set to 0.
- A Pinwheel DAO Resolution with the hash QmYJUvw5xbAJmJknG2xUKDLe424JSTWQQhbJCnucRRjUv7 will be approved.
- The Aave-SparkLend Revenue Share payment for Q3 2024 will be distributed.
- A Spark proxy spell at 0xcc3B9e79261A7064A0f734Cc749A8e3762e0a187 will be executed.
- The Seal Engine will be initialized. This requires a number of sub-actions:
- Office hours value in the Exec Doc matches the spell
- Sum of all payments in the Exec Doc matches the tests
- Exec Doc URL in the spell comment matches your Raw Exec Doc URL above
- Exec Doc URL in the spell comment refers to the https://github.com/makerdao/community repository
- Every action present in the spell code is present in the Exec Doc
- Every action in the Exec Doc is present in the spell code
- Exec Doc for the specified date is found in the
IF new commits are present in the spell-
Copy relevant checklist items from the above and redo them -
Ensure newly added code is covered by tests -
Check if chainlog needs to be updated -
Copy over and redo "Tests" section from the above
-
- IF all checks pass, make sure to include explicit "Good to deploy" comment
The spell was deployed to https://etherscan.io/address/0xACA9a90C92647e3d3f04095118192DC80C470955#code |
TL;DR: good to handover 👋🏻 Deployed Stage
|
Good to handover :) Deployed Stage
|
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.
Approved :)
Handover and Merge Stage
- Check that the spell address posted by the crafter in
new-spells
is correct - Confirm the address in the
new-spells
channel (via a separate "reply to" message, restating the address to avoid edits)- Wait until responsible governance facilitator confirms handover in
new-spells
- Wait until responsible governance facilitator confirms handover in
- Ensure that no changes were made to the code since the spell was deployed and archived
- Approve spell PR for merge via 'Approve' review option
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.
TL;DR: Good to merge 🔀
Handover and Merge Stage
- Check that the spell address posted by the crafter in
new-spells
is correct - Confirm the address in the
new-spells
channel (via a separate "reply to" message, restating the address to avoid edits)- Wait until responsible governance facilitator confirms handover in
new-spells
- Wait until responsible governance facilitator confirms handover in
- Ensure that no changes were made to the code since the spell was deployed and archived
- Approve spell PR for merge via 'Approve' review option
Description
Mainnet executive spell implemented according to the relevant Exec Sheet and Exec Doc.
Contribution Checklist
Checklist
officeHours
modifier override30 days
unless otherwise specified)ETH_GAS_LIMIT="XXX" ETH_GAS_PRICE="YYY" make deploy
mainnet
contract on etherscanmake archive-spell
ormake date="YYYY-MM-DD" archive-spell
to make an archive directory and copyDssSpell.sol
,DssSpell.t.sol
,DssSpell.t.base.sol
, andDssSpellCollateralOnboarding.sol
squash and merge
this PR