Skip to content
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-31 #435

Merged
merged 27 commits into from
Nov 1, 2024
Merged

Mainnet Spell 2024-10-31 #435

merged 27 commits into from
Nov 1, 2024

Conversation

0xdecr1pto
Copy link
Contributor

Description

Contribution Checklist

  • PR title starts with (PE-<TICKET_NUMBER>)
  • Code approved
  • Tests approved
  • CI Tests pass

Checklist

  • Every contract variable/method declared as public/external private/internal
  • Consider if this PR needs the officeHours modifier override
  • Verify expiration (30 days unless otherwise specified)
  • Verify hash in the description matches here
  • Validate all addresses used are in changelog or known
  • Notify any external teams affected by the spell so they have the opportunity to review
  • Deploy spell ETH_GAS_LIMIT="XXX" ETH_GAS_PRICE="YYY" make deploy
  • Verify mainnet contract on etherscan
  • Change test to use mainnet spell address and deploy timestamp
  • Run make archive-spell or make date="YYYY-MM-DD" archive-spell to make an archive directory and copy DssSpell.sol, DssSpell.t.sol, DssSpell.t.base.sol, and DssSpellCollateralOnboarding.sol
  • squash and merge this PR

Copy link
Contributor

@amusingaxl amusingaxl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a reviewer, but here are my 2 cents.

src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/test/config.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.base.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
@0xdecr1pto 0xdecr1pto marked this pull request as ready for review October 29, 2024 16:23
@0xdecr1pto 0xdecr1pto self-assigned this Oct 29, 2024
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/test/addresses_base.sol Outdated Show resolved Hide resolved
src/DssSpell.t.base.sol Outdated Show resolved Hide resolved
src/DssSpell.t.base.sol Show resolved Hide resolved
src/DssSpell.t.sol Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.base.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.t.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Outdated Show resolved Hide resolved
src/DssSpell.sol Show resolved Hide resolved
@SidestreamStrongStrawberry
Copy link
Collaborator

tldr; Good to deploy

Disclaimer: it is not technically possible to ensure that 4 new validator addresses (1, 2, 3, 4 added via this spell to BTC/USD, ETH/USD, WSTETH/USD, MKR/USD medians) belong to different independent entities. In the following review, we trusted the forum post which shared the validator addresses.

Development Stage

  • Preparation
    • Exec Sheet for the specified date is found in the "Executive Vote Implementation Process" google sheet
      Insert URL to the specific sheet here
      https://docs.google.com/spreadsheets/d/1w_z5WpqxzwreCcaveB2Ye1PP5B8QAHDglzyxKHG3CHw/edit?gid=842629197#gid=842629197
    • Using Exec Sheet URL from the above, read spell instructions from the Exec Sheet and list them below
      List all instructions announced in the Exec Sheet
      • Init Base Native Bridge
        • Init Base Token Bridge for USDS, sUSDS by calling TokenBridgeInit.initBridges using the following parameters:
          • Set l1BridgeInstance with the following parameters:
            • Set parameter l1BridgeInstance.govRelay: (L1GovernanceRelay: 0x1Ee0AE8A993F2f5abDB51EAF4AC2876202b65c3b)
            • Set parameter l1BridgeInstance.escrow: (Escrow: 0x7F311a4D48377030bD810395f4CCfC03bdbe9Ef3)
            • Set parameter l1BridgeInstance.bridge: (ERC1967Proxy: 0xA5874756416Fa632257eEA380CAbd2E87cED352A)
            • Set parameter l1BridgeInstance.bridgeImp: (L1TokenBridge: 0xaeFd31c2e593Dc971f9Cb42cBbD5d4AD7F1970b6)
          • Set l2BridgeInstance with the following parameters (Base Network):
            • Set parameter l2BridgeInstance.govRelay: (L2GovernanceRelay: 0xdD0BCc201C9E47c6F6eE68E4dB05b652Bb6aC255)
            • Set parameter l2BridgeInstance.bridge: (ERC1967Proxy: 0xee44cdb68D618d58F75d9fe0818B640BD7B8A7B7)
            • Set parameter l2BridgeInstance.bridgeImp: (L2TokenBridge: 0x289A37BE5D6CCeF7A8f2b90535B3BB6bD3905f72)
            • Set parameter l2BridgeInstance.spell: (L2TokenBridgeSpell: 0x6f29C3A29A3F056A71FB0714551C8D3547268D62)
          • Set cfg with the following parameters:
            • Set parameter cfg.l1Messenger: (l1messenger 0x866E82a600A1414e583f7F13623F1aC5d58b0Afa)
            • Set parameter cfg.l2Messenger: (l2messenger 0x4200000000000000000000000000000000000007)
            • Set parameter cfg.l1Tokens: (USDS, SUSDS on mainnet)
            • Set parameter cfg.l2Tokens: (USDS: 0x820C137fa70C8691f0e44Dc420a5e53c168921Dc, sUSDS: 0x5875eEE11Cf8398102FdAd704C9E96607675467a on Base chain)
            • Set parameter cfg.maxWithdraws: (type(uint256).max for each token)
            • Set parameter cfg.minGasLimit: (500,000)
            • Set parameter cfg.govRelayCLKey: (chainlog key for govRelay -> BASE_GOV_RELAY)
            • Set parameter cfg.escrowCLKey: (chainlog key for Escrow -> BASE_ESCROW)
            • Set parameter cfg.l1BridgeCLKey: (chainlog key for L1TokenBridge -> BASE_TOKEN_BRIDGE)
            • Set parameter cfg.l1BridgeImpCLKey: (chainlog key for L1TokenBridgeImp -> BASE_TOKEN_BRIDGE_IMP)
      • Init Allocator System for Spark Subdao Proxy
        • Init shared components for Allocator System be calling AllocatorInit.initShared
          • Set parameter sharedInstance.oracle: (Allocator Oracle: 0xc7B91C401C02B73CBdF424dFaaa60950d5040dB7)
          • Set parameter sharedInstance.roles: (AllocatorRoles: 0x9A865A710399cea85dbD9144b7a09C889e94E803)
          • Set parameter sharedInstance.registry: (AllocatorRegistry: 0xCdCFA95343DA7821fdD01dc4d0AeDA958051bB3B)
        • Init Allocator ILK for Spark Subdao by calling AllocatorInit.initIlk using the following parameters:
          • Set sharedInstance with the following parameters:
            • Set parameter sharedInstance.oracle: (Allocator Oracle: 0xc7B91C401C02B73CBdF424dFaaa60950d5040dB7)
            • Set parameter sharedInstance.roles: (AllocatorRoles: 0x9A865A710399cea85dbD9144b7a09C889e94E803)
            • Set parameter sharedInstance.registry: (AllocatorRegistry: 0xCdCFA95343DA7821fdD01dc4d0AeDA958051bB3B)
          • Set ilkInstance with the following parameters:
            • Set parameter ilkInstance.owner: (MCD_PAUSE_PROXY)
            • Set parameter ilkInstance.vault: (AllocatorVault: 0x691a6c29e9e96dd897718305427Ad5D534db16BA)
            • Set parameter ilkInstance.buffer: (AllocatorBuffer: 0xc395D150e71378B47A1b8E9de0c1a83b75a08324)
          • Set cfg with the following parameters:
            • Set parameter cfg.ilk: (ALLOCATOR-SPARK-A)
            • Set parameter cfg.duty: (5.2% -> 1000000001607468111246255079)
            • Set parameter cfg.gap: (10,000,000)
            • Set parameter cfg.maxLine: (10,000,000)
            • Set parameter cfg.ttl: (86,400 seconds)
            • Set parameter cfg.allocatorProxy: 0x3300f198988e4C9C63F75dF86De36421f06af8c4
            • Set parameter cfg.ilkRegistry: 0x5a464c28d19848f44199d003bef5ecc87d090f87
      • Whitelist Spark ALM Proxy on the PSM
        • IPSMLike(MCD_LITE_PSM_USDC_A).kiss(almProxy: 0x1601843c5E9bC251A3272907010AFa41Fa18347E);
      • Add new validators for Median (Medianizer)
        • Add ETH Global validator 0xcfC62b2269521e3212Ce1b6670caE6F0e34E8bF3 to the following median contracts
        • Add Mantle validator 0xFa6eb665e067759ADdE03a8E6bD259adBd1D70c9 to the following median contracts
        • Add Nethermind validator 0x91242198eD62F9255F2048935D6AFb0C2302D147 to the following median contracts
        • Add Euler validator 0x1DCB8CcC022938e102814F1A299C7ae48A8BAAf6to the following median contracts
        • Add all validators declared above to BTC/USD median contract at 0xe0F30cb149fAADC7247E953746Be9BbBB6B5751f
        • Add all validators declared above to ETH/USD median contract at 0x64DE91F5A373Cd4c28de3600cB34C7C6cE410C85
        • Add all validators declared above to WSTETH/USD median contract at 0x2F73b6567B866302e132273f67661fB89b5a66F2
        • Add all validators declared above to MKR/USD median contract at 0xdbBe5e9B1dAa91430cF0772fCEbe53F6c6f137DF
  • 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 to false
    • Office hours value matches the Exec Sheet
    • 30 days spell expiry set in the constructor (block.timestamp + 30 days)
  • 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)"
  • 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
      ⚠️ This is not followed. But it is acceptable for better readability
    • 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 and Authority URL is present in the spell code under relevant section or instruction (depending on which row the url is present)
      ⚠️ The url is only added for the section but it's acceptable as all the url in the same section point to the same page
    • Every proof url from the Exec Sheet, such as Reasoning URL and Authority URL have prefix derived from the url itself
      • // Executive Vote: if URL starts with https://vote.makerdao.com/executive/
      • // Poll: if URL starts with https://vote.makerdao.com/polling/
      • // Forum: if URL starts with https://forum.makerdao.com/t/
      • // MIP: if URL starts with https://mips.makerdao.com/mips/details/
  • Dependency checks
    • Update Foundry by running foundryup
    • Reinstall libraries by running rm -rf ./lib && git submodule update --init --recursive
      Insert checked out submodule paths here
      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 'a8a7b151c39282d4ddab8cb4ead2d80342df588f'
      Submodule path 'lib/dss-test/lib/dss-interfaces': checked out '9bfd7afadd1f8c217ef05850b2555691786286cb'
      Submodule path 'lib/dss-test/lib/forge-std': checked out '978ac6fadb62f5f0b723c996f64be52eddba6801'
    • IF submodule upgrades are present, make sure dss-exec-lib is synced as well
    • git submodule hash of dss-exec-lib (run git submodule status) matches the latest release version or newer
    • dss-interfaces library used inside lib/dss-exec-lib matches submodule used inside lib/dss-test
  • 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";)
    • 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)
      • Each static interface declare only functions actually used in the spell code
  • 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
    • 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
    • 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
    • IF timestamps are present
      • Comment above timestamp states full date including UTC timezone
      • Timestamp converts back to the correct date
      • Timestamp converts back to the UTC timezone
      • Variable naming matches MMM_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 as internal
      • Each variable state mutability is declared as constant
  • IF new contract is present in the spell (not yet on chainlog or new to chainlog)
    • ALLOCATOR_REGISTRY (deployed at 0xCdCFA95343DA7821fdD01dc4d0AeDA958051bB3B)
      • 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 was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
    • ALLOCATOR_ROLES (deployed at 0x9A865A710399cea85dbD9144b7a09C889e94E803)
      • 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 was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
    • PIP_ALLOCATOR (deployed at 0xc7B91C401C02B73CBdF424dFaaa60950d5040dB7)
      • 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 was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
    • ALLOCATOR_SPARK_BUFFER (deployed at 0xc395D150e71378B47A1b8E9de0c1a83b75a08324)
      • 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 was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
    • ALLOCATOR_SPARK_VAULT (deployed at 0x691a6c29e9e96dd897718305427Ad5D534db16BA)
      • 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, ...)
        • roles_ address: matches deployed ALLOCATOR_ROLES address
        • buffer_ address: matches deployed ALLOCATOR_SPARK_BUFFER address
        • ilk_ bytes32: matches bytes32 format of ALLOCATOR-SPARK-A
        • usdsJoin_ address: matches USDS_JOIN in chainlog
      • IF new contract have concept of wards or access control
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
    • L2USDS (deployed at 0x820C137fa70C8691f0e44Dc420a5e53c168921Dc)
      • Source code is verified on etherscan
      • Compilation optimizations match deployment settings defined in the source code repo
      • GNU AGPLv3 license
        ⚠️ The source code has MIT license, but as the contract wasn't developed by MakerDAO, we do not have control over it
      • Every maker-related constructor argument matches chainlog (e.g. vat, dai, dog, ...)
      • IF new contract have concept of wards or access control
        ℹ️ While the contract itself have no wards, it keeps state for the implementation contract (called via delegatecall, as per EIP1967 spec). Upgradability is also being controlled by the implementation contract (see _authorizeUpgrade)
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
          ⚠️ As PAUSE_PROXY is not deployed on Base, L2_BASE_GOV_RELAY is relied and it is expected.
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
          ⚠️ As PAUSE_PROXY is not deployed on Base, L2_BASE_GOV_RELAY is relied and it is expected. The above check was done with L2_BASE_GOV_RELAY
      • 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
        ⚠️ As the contract is deployed on Base, the deployer is not expected to be included in addresses_deployers.sol.
    • L2USDSIMP (deployed at 0x191CD41681a3fE15aa15a0bec415821CE24CAd5e)
      • 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
        ℹ️ While the contract has wards, since it's only an implementation contract and called via delegatecall, its state is stored in the parent proxy contract. Therefore its own state is irrelevant
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • 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
        ⚠️ As the contract is deployed on Base, the deployer is not expected to be included in addresses_deployers.sol.
    • L2SUSDS (deployed at 0x5875eEE11Cf8398102FdAd704C9E96607675467a)
      • Source code is verified on etherscan
      • Compilation optimizations match deployment settings defined in the source code repo
      • GNU AGPLv3 license
        ⚠️ The source code has MIT license, but as the contract wasn't developed by MakerDAO, we do not have control over it
      • Every maker-related constructor argument matches chainlog (e.g. vat, dai, dog, ...)
      • IF new contract have concept of wards or access control
        ℹ️ While the contract itself have no wards, it keeps state for the implementation contract (called via delegatecall, as per EIP1967 spec). Upgradability is also being controlled by the implementation contract (see _authorizeUpgrade)
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
          ⚠️ As PAUSE_PROXY is not deployed on Base, L2_BASE_GOV_RELAY is relied and it is expected.
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
          ⚠️ As PAUSE_PROXY is not deployed on Base, L2_BASE_GOV_RELAY is relied and it is expected. The above check was done with L2_BASE_GOV_RELAY
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Used release v5.0 source code repo
      • Deployer address is included into addresses_deployers.sol
        ⚠️ As the contract is deployed on Base, the deployer is not expected to be included in addresses_deployers.sol.
    • L2SUSDSIMP (deployed at 0x982f2DF63Fe38AB8d55f4B1464e8cfDc8eA5dEC8)
      • 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
        ℹ️ While the contract has wards, since it's only an implementation contract and called via delegatecall, its state is stored in the parent proxy contract. Therefore its own state is irrelevant
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
        ⚠️ As the contract is deployed on Base, the deployer is not expected to be included in addresses_deployers.sol.
    • BASE_ESCROW (deployed at 0x7F311a4D48377030bD810395f4CCfC03bdbe9Ef3)
      • 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 was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
    • BASE_TOKEN_BRIDGE (deployed at 0xA5874756416Fa632257eEA380CAbd2E87cED352A)
      • Source code is verified on etherscan
      • Compilation optimizations match deployment settings defined in the source code repo
      • GNU AGPLv3 license
        ⚠️ The source code has MIT license, but as the contract wasn't developed by MakerDAO, we do not have control over it
      • Every maker-related constructor argument matches chainlog (e.g. vat, dai, dog, ...)
      • IF new contract have concept of wards or access control
        ℹ️ While the contract itself have no wards, it keeps state for the implementation contract (called via delegatecall, as per EIP1967 spec). Upgradability is also being controlled by the implementation contract (see _authorizeUpgrade)
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Used release v5.0 source code repo
      • Deployer address is included into addresses_deployers.sol
    • BASE_TOKEN_BRIDGE_IMP (deployed at 0xaeFd31c2e593Dc971f9Cb42cBbD5d4AD7F1970b6)
      • 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, ...)
        • _otherBridge address: matches deployed L2_BASE_TOKEN_BRIDGE
        • _messenger address: matches L1CrossDomainMessenger found here
      • IF new contract have concept of wards or access control
        ℹ️ While the contract has wards, since it's only an implementation contract and called via delegatecall, its state is stored in the parent proxy contract. Therefore its own state is irrelevant
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
    • BASE_GOV_RELAY (deployed at 0x1Ee0AE8A993F2f5abDB51EAF4AC2876202b65c3b)
      • 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, ...)
        • _l2GovernanceRelay address: matches deployed L2_BASE_GOV_RELAY
        • _l1Messenger address: matches L1CrossDomainMessenger found here
      • IF new contract have concept of wards or access control
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
    • L2_BASE_TOKEN_BRIDGE (deployed at 0xee44cdb68D618d58F75d9fe0818B640BD7B8A7B7)
      • Source code is verified on etherscan
      • Compilation optimizations match deployment settings defined in the source code repo
      • GNU AGPLv3 license
        ⚠️ The source code has MIT license, but as the contract wasn't developed by MakerDAO, we do not have control over it
      • Every maker-related constructor argument matches chainlog (e.g. vat, dai, dog, ...)
      • IF new contract have concept of wards or access control
        ℹ️ While the contract itself have no wards, it keeps state for the implementation contract (called via delegatecall, as per EIP1967 spec). Upgradability is also being controlled by the implementation contract (see _authorizeUpgrade)
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
          ⚠️ As PAUSE_PROXY is not deployed on Base, L2_BASE_GOV_RELAY is relied and it is expected.
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
          ⚠️ As PAUSE_PROXY is not deployed on Base, L2_BASE_GOV_RELAY is relied and it is expected. The above check was done with L2_BASE_GOV_RELAY
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Used release v5.0 source code repo
      • Deployer address is included into addresses_deployers.sol
        ⚠️ As the contract is deployed on Base, the deployer is not expected to be included in addresses_deployers.sol.
    • L2_BASE_TOKEN_BRIDGE_IMP (deployed at 0x289A37BE5D6CCeF7A8f2b90535B3BB6bD3905f72)
      • 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, ...)
        • _otherBridge address: matches deployed BASE_TOKEN_BRIDGE
        • _messenger address: matches L2CrossDomainMessenger found here
      • IF new contract have concept of wards or access control
        ℹ️ While the contract has wards, since it's only an implementation contract and called via delegatecall, its state is stored in the parent proxy contract. Therefore its own state is irrelevant
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
        ⚠️ As the contract is deployed on Base, the deployer is not expected to be included in addresses_deployers.sol.
    • L2_BASE_TOKEN_BRIDGE_SPELL (deployed at 0x6f29C3A29A3F056A71FB0714551C8D3547268D62)
      • 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, ...)
        • l2Bridge_ address: matched deployed L2_BASE_TOKEN_BRIDGE
      • IF new contract have concept of wards or access control
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
        ⚠️ As the contract is deployed on Base, the deployer is not expected to be included in addresses_deployers.sol.
    • L2_BASE_GOV_RELAY (deployed at 0xdD0BCc201C9E47c6F6eE68E4dB05b652Bb6aC255)
      • 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, ...)
        • _l1GovernanceRelay address: matches deployed BASE_GOV_RELAY
        • _l2Messenger address: matches L2CrossDomainMessenger found here
      • IF new contract have concept of wards or access control
        • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        • Ensure that contract deployer address was denied (wards(deployer) is 0)
        • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
      • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
        • Audited contract code repo
      • Deployer address is included into addresses_deployers.sol
        ⚠️ As the contract is deployed on Base, the deployer is not expected to be included in addresses_deployers.sol.
  • IF core system parameter changes are present in the instructions
  • IF debt ceiling changes are present in the instructions
  • IF additional dependencies (i.e. ./src/dependencies/ directory) are present:
    • op-token-bridge
      • IF the dependencies contracts/libraries have been audited
      • 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
    • dss-allocator
      • 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
        • Matches with audited commit 226584d3b179d98025497815adb4ea585ea0102d
        • 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 onboarding is present
    • Insert and follow the relevant checklists below:

      Collateral Onboarding Checklist

      ℹ️ The collateral onboarding checklist doesn't fully match with collateral class 5
      • 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)
            • constructor args are correct
              ℹ️ The Oracle contract is different and doesn't have a constructor
              • src (medianizer)
            • check wards
              ℹ️ The Oracle contract is different and doesn't have a ward concept
              • MCD_PAUSE_PROXY is relied
              • deployer is denied
              • no other address has been relied
          • deployed via Factory (LPs)
            ℹ️ The contract was deployed by EOA but it is expected since the Oracle contract is non-standard
        • Join (Join Adapter)
          ℹ️ The collateral doesn't have join adapter as it is not meant to be liquidated
          • 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 authed join access)
            • parameters are correct
              • owner matches MCD Pause Proxy
              • ilk is the bytes32 representation of "TOKEN-A"
                • cast --to-ascii <bytes32> matches ASCII Ilk
                • cast --to-bytes32 $(cast --from-ascii "TOKEN-A") matches bytes32
              • gem matches token contract
        • Clip
          ℹ️ The collateral doesn't have Clip as it is not meant to be liquidated
          • 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 the bytes32 representation of "TOKEN-A"
                • cast --to-ascii <bytes32> matches ASCII Ilk
                • cast --to-bytes32 $(cast --from-ascii "TOKEN-A") matches bytes32
        • Calc
          ℹ️ The collateral doesn't have Calc as it is not meant to be liquidated
          • deployed via CalcFab
            • Fab matches chainlog
            • newStairstepExponentialDecrease
            • newLinearDecrease
            • newExponentialDecrease
            • parameters are correct
              • owner matches MCD Pause Proxy
        • Risk Parameters
        • Autoline (setIlkAutoLineParameters)
          • ilk
          • line
          • gap
          • ttl
        • Onboarding Actions
          • ensure DssExecLib.addNewCollateral is used
            ℹ️ It was done in dss-allocator dependency
          • ensure CollateralOpts is used
            ℹ️ CollateralOpts wasn't used because DssExecLib.addNewCollateral was not used and it is expected
            • ilk follows the ilk format TOKEN-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 IF pip is OSM
            • whitelistOSM set to true IF median is src in OSM
            • ilkDebtCeiling (vat.ilk.line) in DAI (e.g. 1 * MILLION)
              • IF autoline is enabled, vat.ilk.line should be set to DC-IAM gap value
            • minVaultAmount (vat.ilk.dust) in DAI (e.g. 15_000)
              • ensure clip.tip is adjusted proportionally to vat.ilk.dust (e.g. lower the dust lower the tip)
            • maxLiquidationAmount (dog.ilk.hole) in DAI (e.g. 5 * MILLION)
              • ensure dog.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 format TOKEN-A
            • linein DAI (e.g. 10 * MILLION)
            • gap in DAI (e.g. 1 * MILLION)
            • ttl in seconds (e.g. 8 hours)
        • New Chainlog Entries
          • TOKEN
          • PIP_TOKEN
          • MCD_JOIN_TOKEN_A
          • MCD_CLIP_TOKEN_A
          • MCD_CLIP_CALC_TOKEN_A
        • Chainlog Bump
          • Patch x.x.1
        • Test Coverage (Follow Previous Test Patterns)
          • testCollateralIntegrations
            ℹ️ Tested via testAllocatorIntegration
          • testNewChainlogValues
            ⚠️ The above test is not used anymore and chainlog values are tested via testChainlogIntegrity and testChainlogValues
          • testNewIlkRegistryValues
            ℹ️ Tested via testAllocatorIntegration
          • 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
  • IF PSM migration, onboarding or offboarding is present:
  • IF D3M onboarding is present, insert and follow D3M Checklist
  • IF collateral offboarding is present in the spell
    • 1st stage collateral offboarding
      • Collateral type (ilk) is removed from AutoLine (MCD_IAM_AUTO_LINE) IF currently enabled
      • Collateral debt ceiling (vat.ilk.line) is set to 0
      • Global debt ceiling (vat.Line) decreased by the total amount of offboarded ilks
    • 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 to 0 IF requested by governance
      • Flat keeper incentive (tip) is set to 0 IF requested by governance
      • Relative keeper incentive (chip) is set to 0 IF requested by governance
      • Max liquidation amount (hole) is adjusted via DssExecLib.setIlkMaxLiquidationAmount(ilk, amount) IF requested by governance
      • Relevant clipper contract (MCD_CLIP_) is active (i.e. stopped is 0)
      • Liquidations are triggered via (depending on governance instruction):
        • EITHER liquidation ratio (spotter.ilk.mat) being set very high in the spell (using DssExecLib.setValue(DssExecLib.spotter(), ilk, "mat", ratio))
        • OR via enabling linear interpolation (DssExecLib.linearInterpolation(name, target, ilk, what, startTime, start, end, duration))
          • Ensure name format matches "XXX-X Offboarding"
          • Ensure target matches DssExecLib.spotter() address
          • Ensure ilk format matches collateral type (ilk) name ("XXX-X")
          • Ensure what matches string "mat"
          • Ensure startTime matches block.timestamp
          • Ensure start uses variable CURRENT_XXX_A_MAT
          • Ensure start matches current spotter.ilk.mat value
          • Ensure end uses variable TARGET_XXX_A_MAT
          • Ensure end value matches the instruction
          • Ensure end allows liquidation of all remaining vaults (end is bigger than collateral_type_collateralization_ratio * risk_multiplier_factor)
          • Ensure duration matches the instruction
      • Spotter price is updated via DssExecLib.updateCollateralPrice(ilk) IF collateral have no running oracle (i.e. relevant PIP_ contract have outdated zzz value)
      • Spotter price is updated after all other actions
      • Offboarding is tested at least via _checkIlkClipper helper
  • IF RWA updates are present
    • IF doc is updated
      • _updateDoc helper is copied one-to-one from the archive and defined above actions
      • _updateDoc(ilk, doc) is called in the spell
    • IF debt ceiling is updated
      • IF AutoLine update is requested by the Exec Sheet
      • IF regular debt ceiling (vat.ilk.line) update is requested by the Exec Sheet
      • Liquidation oracle price is bumped via RwaLiquidationOracleLike(MIP21_LIQUIDATION_ORACLE).bump(ilk, val) pattern
        • Comment above bump explains val computation via // Note: the formula is: "debt_ceiling * [ (1 + rwa_stability_fee ) ^ (minimum_deal_duration_in_years) ] * liquidation_ratio"
        • Comment above bump 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 the val 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 existing val value can be retrieved by calling read() on PIP_RWAXX and converting the result into decimal
      • Oracle price is updated via DssExecLib.updateCollateralPrice(ilk)
      • IF soft liquidation explicitly requested to be triggered (via .tell(ilk)) AND debt ceiling is 0 (OR is being set to 0 in the current spell)
        • RwaLiquidationOracle.tell(ilk) call is present
        • IF RWAXX_A_INPUT_CONDUIT is an instance of TinlakeMgr (it is a Centrifuge integration), additional TinlakeMgr.tell() call is present (in order to prevent further TIN redemptions in the Centrifuge pool)
  • IF payments are present in the spell
    • IF MKR 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
      • Transfer amount is specified with (at least) 2 decimals using ether keyword
      • IF ether 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 via testMKRPayments test
      • Sum of all MKR transfers tested in testMKRPayments 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
      • Sum of all DAI transfers tested in testDAIPayments matches number in the Exec Sheet
    • IF MKR or DAI streams (DssVest) are created
      • VestAbstract interface is imported from dss-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 in addresses_wallets.sol
      • tot (Total stream amount) matches Exec Sheet
      • IF ether 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 as bgn - fin (i.e. MONTH_DD_YYYY - MONTH_DD_YYYY)
      • fin (Vest end timestamp) matches Exec Sheet
      • eta (Vest cliff duration) matches the following logic
        • IF eta is explicitly specified in the Exec Sheet, then the values match
        • IF eta and clf (Cliff end timestamp) are not specified in the Exec Sheet, then eta is 0
        • IF clf is specified, but clf <= bgn, then eta is 0
        • IF clf is specified and clf > bgn, eta is expressed as clf - bgn (i.e. MONTH_DD_YYYY - MONTH_DD_YYYY)
      • IF mgr (Vest manager address) is specified in the Exec Sheet, matches the value, OTHERWISE matches address(0)
      • Ensure that max vesting rate (cap) is enough for the new streams
        • The maximum vesting rate (tot divided by tau) <= the maximum vest streaming rate (cap)
        • The maximum vesting rate (tot divided by tau) > the maximum vest streaming rate (cap)
        • Calculate new cap value equal to 10% greater than the new maximum vesting rate, then round new cap 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 cumulative total (the sum of all tot values)
        • Ensure allowance increase follows archive patterns
      • Tested via testVestDAI or testVestMKR
    • IF MKR or DAI vest termination (Yank) is present
      • Yanked stream ID matches Exec Sheet
      • MCD_VEST_MKR_TREASURY chainlog address is used for MKR stream yank
      • MCD_VEST_DAI chainlog address is used for DAI stream yank
      • Tested via testYankDAI or testYankMKR
  • 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
      • 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 Proxy DelegateCall context)
      • No SubDAO contract being interacted with is authed on a core contract like vat, 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 the PAUSE_PROXY as their admin (i.e. the party that can upgrade)
        • Any upgradable SubDAO contracts with an admin that is not PAUSE_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 external contracts calls are present (Not SubDAOs, e.g. Starknet)
    • Target Contract doesn't block spell execution
    • External call is NOT delegatecall
    • Target Contract doesn't have permissions on the Vat
    • Target Contract doesn't do anything untoward (e.g. interacting with unsafe contracts)
    • Contracts deployed via CREATE2 (e.g. if it looks like a vanity address) do not have selfdestruct 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 and testChainlogValues
  • Ensure every spell variable is declared as public/internal
  • Ensure immutable visibility is only used when fetching addresses from the ChainLog via DssExecLib.getChangelogAddress(key) and constant is used instead for static addresses
    • Fetch addresses as type address and wrap with Like suffix interfaces inline (when making calls), UNLESS archive patterns permit otherwise (Such as MKR)
    • 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 than vat), except where the archive pattern differs from this pattern (e.g. MKR)
  • 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
      Insert most recent commit hash where CI was passing
      57a5fb7
    • 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 the skipped modifier
    • Ensure each spell action has sufficient test coverage
      List actions for which coverage was checked here
      • Init Base Native Bridge
        • Init Base Token Bridge for USDS, sUSDS by calling TokenBridgeInit.initBridges using the following parameters:
          • tested via testBaseTokenBridgeIntegration, testChainlogIntegrity and testChainlogValues
      • Init Allocator System for Spark Subdao Proxy
        • Init shared components for Allocator System be calling AllocatorInit.initShared
          • tested via testChainlogIntegrity and testChainlogValues
        • Init Allocator ILK for Spark Subdao by calling AllocatorInit.initIlk using the following parameters:
          • tested via testAllocatorIntegration and testGeneral
      • Whitelist Spark ALM Proxy on the PSM
        • tested via testsWhitelistSparkProxyOnLitePsm
      • Add new validators for Median (Medianizer)
        • tested via testMedianValidators
      • Add all validators declared above to BTC/USD median contract at 0xe0F30cb149fAADC7247E953746Be9BbBB6B5751f
        • tested via testMedianValidators
    • 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.
_Insert your local test logs here_
Ran 2 tests for src/test/starknet.t.sol:StarknetTests
[PASS] testStarknet() (gas: 3037996)
[PASS] testStarknetSpell() (gas: 2287)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 43.46s (39.49s CPU time)

Warning: the following cheatcode(s) are deprecated and will be removed in future versions:
  revertTo(uint256): replaced by `revertToState`
  snapshot(): replaced by `snapshotState`
Ran 42 tests for src/DssSpell.t.sol:DssSpellTest
[PASS] testAllocatorIntegration() (gas: 3126213)
[PASS] testBaseTokenBridgeIntegration() (gas: 267571693)
[SKIP] testBytecodeMatches() (gas: 0)
[PASS] testCastCost() (gas: 2896263)
[PASS] testCastOnTime() (gas: 2892530)
[PASS] testChainlogIntegrity() (gas: 8377481)
[PASS] testChainlogValues() (gas: 10878844)
[SKIP] testCollateralIntegrations() (gas: 0)
[PASS] testContractSize() (gas: 14875)
[SKIP] testDaoResolutions() (gas: 0)
[PASS] testDeployCost() (gas: 3347481)
[SKIP] testEsmAuth() (gas: 0)
[PASS] testGeneral() (gas: 29109305)
[SKIP] testIlkClipper() (gas: 0)
[SKIP] testL2ArbitrumSpell() (gas: 0)
[SKIP] testL2OptimismSpell() (gas: 0)
[SKIP] testLerpSurplusBuffer() (gas: 0)
[PASS] testLitePSMs() (gas: 3795083)
[SKIP] testLockstakeIlkIntegration() (gas: 0)
[SKIP] testMedianReaders() (gas: 0)
[PASS] testMedianValidators() (gas: 2942102)
[SKIP] testNewAuthorizations() (gas: 0)
[SKIP] testNewCronJobs() (gas: 0)
[PASS] testNextCastTime() (gas: 344189)
[SKIP] testOffboardings() (gas: 0)
[PASS] testOfficeHours() (gas: 15575)
[SKIP] testOracleList() (gas: 0)
[SKIP] testOsmReaders() (gas: 0)
[PASS] testPSMs() (gas: 4097732)
[SKIP] testPayments() (gas: 0)
[SKIP] testRemoveChainlogValues() (gas: 0)
[PASS] testRevertIfNotScheduled() (gas: 16808)
[SKIP] testSparkSpellIsExecuted() (gas: 0)
[PASS] testSplitter() (gas: 3496662)
[PASS] testSystemTokens() (gas: 3981469)
[PASS] testUseEta() (gas: 343178)
[SKIP] testVestDAI() (gas: 0)
[SKIP] testVestMKR() (gas: 0)
[SKIP] testVestSKY() (gas: 0)
[SKIP] testYankDAI() (gas: 0)
[SKIP] testYankMKR() (gas: 0)
[PASS] testsWhitelistSparkProxyOnLitePsm() (gas: 2893935)
Suite result: ok. 19 passed; 0 failed; 23 skipped; finished in 351.77s (910.15s CPU time)

Ran 2 test suites in 352.54s (395.23s CPU time): 21 tests passed, 0 failed, 23 skipped (44 total tests)

Pre-Deployment Stage

@0xp3th1um
Copy link
Collaborator

Good to deploy!

Note: Some checks related to collateral onboarding could not be performed because they don't apply in this case and the checklist is made for a different kind of collateral. Additionally, the licenses for contracts are not the requires ones but this is ok since they were developed by a third party.

Mainnet Executive Spell Review Checklist

Development Stage

  • Preparation

    • Exec Sheet for the specified date is found in the "Executive Vote Implementation Process" google sheet
      Insert URL to the specific sheet here
      https://docs.google.com/spreadsheets/d/1w_z5WpqxzwreCcaveB2Ye1PP5B8QAHDglzyxKHG3CHw/edit?gid=842629197#gid=842629197
    • Using Exec Sheet URL from the above, read spell instructions from the Exec Sheet and list them below
      List all instructions announced in the Exec Sheet
      • Init Base Native Bridge

      • Init Base Token Bridge for USDS, sUSDS by calling TokenBridgeInit.initBridges using the following parameters:

        • Set l1BridgeInstance with the following parameters:

          • Set parameter l1BridgeInstance.govRelay: (L1GovernanceRelay: 0x1Ee0AE8A993F2f5abDB51EAF4AC2876202b65c3b)
          • Set parameter l1BridgeInstance.escrow: (Escrow: 0x7F311a4D48377030bD810395f4CCfC03bdbe9Ef3)
          • Set parameter l1BridgeInstance.bridge: (ERC1967Proxy: 0xA5874756416Fa632257eEA380CAbd2E87cED352A)
          • Set parameter l1BridgeInstance.bridgeImp: (L1TokenBridge: 0xaeFd31c2e593Dc971f9Cb42cBbD5d4AD7F1970b6)
        • Set l2BridgeInstance with the following parameters (Base Network):

          • Set parameter l2BridgeInstance.govRelay: (L2GovernanceRelay: 0xdD0BCc201C9E47c6F6eE68E4dB05b652Bb6aC255)
          • Set parameter l2BridgeInstance.bridge: (ERC1967Proxy: 0xee44cdb68D618d58F75d9fe0818B640BD7B8A7B7)
          • Set parameter l2BridgeInstance.bridgeImp: (L2TokenBridge: 0x289A37BE5D6CCeF7A8f2b90535B3BB6bD3905f72)
          • Set parameter l2BridgeInstance.spell: (L2TokenBridgeSpell: 0x6f29C3A29A3F056A71FB0714551C8D3547268D62)
        • Set cfg with the following parameters:

          • Set parameter cfg.l1Messenger: (l1messenger 0x866E82a600A1414e583f7F13623F1aC5d58b0Afa)
          • Set parameter cfg.l2Messenger: (l2messenger 0x4200000000000000000000000000000000000007)
          • Set parameter cfg.l1Tokens: (USDS, SUSDS on mainnet)
          • Set parameter cfg.l2Tokens: (USDS: 0x820C137fa70C8691f0e44Dc420a5e53c168921Dc, sUSDS: 0x5875eEE11Cf8398102FdAd704C9E96607675467a on Base chain)
          • Set parameter cfg.maxWithdraws: (type(uint256).max for each token)
          • Set parameter cfg.minGasLimit: (500,000)
          • Set parameter cfg.govRelayCLKey: (chainlog key for govRelay -> BASE_GOV_RELAY)
          • Set parameter cfg.escrowCLKey: (chainlog key for Escrow -> BASE_ESCROW)
          • Set parameter cfg.l1BridgeCLKey: (chainlog key for L1TokenBridge -> BASE_TOKEN_BRIDGE)
          • Set parameter cfg.l1BridgeImpCLKey: (chainlog key for L1TokenBridgeImp -> BASE_TOKEN_BRIDGE_IMP)
      • Init Allocator System for Spark Subdao Proxy

      • Init shared components for Allocator System be calling AllocatorInit.initShared

        • Set parameter sharedInstance.oracle: (Allocator Oracle: 0xc7B91C401C02B73CBdF424dFaaa60950d5040dB7)
        • Set parameter sharedInstance.roles: (AllocatorRoles: 0x9A865A710399cea85dbD9144b7a09C889e94E803)
        • Set parameter sharedInstance.registry: (AllocatorRegistry: 0xCdCFA95343DA7821fdD01dc4d0AeDA958051bB3B)
      • Init Allocator ILK for Spark Subdao by calling AllocatorInit.initIlk using the following parameters:

      • Set sharedInstance with the following parameters:

        • Set parameter sharedInstance.oracle: (Allocator Oracle: 0xc7B91C401C02B73CBdF424dFaaa60950d5040dB7)
        • Set parameter sharedInstance.roles: (AllocatorRoles: 0x9A865A710399cea85dbD9144b7a09C889e94E803)
        • Set parameter sharedInstance.registry: (AllocatorRegistry: 0xCdCFA95343DA7821fdD01dc4d0AeDA958051bB3B)
      • Set ilkInstance with the following parameters:

        • Set parameter ilkInstance.owner: (MCD_PAUSE_PROXY)
        • Set parameter ilkInstance.vault: (AllocatorVault: 0x691a6c29e9e96dd897718305427Ad5D534db16BA)
        • Set parameter ilkInstance.buffer: (AllocatorBuffer: 0xc395D150e71378B47A1b8E9de0c1a83b75a08324)
      • Set cfg with the following parameters:

        • Set parameter cfg.ilk: (ALLOCATOR-SPARK-A)
        • Set parameter cfg.duty: (5.2% -> 1000000001607468111246255079)
        • Set parameter cfg.gap: (10,000,000)
        • Set parameter cfg.maxLine: (10,000,000)
        • Set parameter cfg.ttl: (86,400 seconds)
        • Set parameter cfg.allocatorProxy: 0x3300f198988e4C9C63F75dF86De36421f06af8c4
        • Set parameter cfg.ilkRegistry: 0x5a464c28d19848f44199d003bef5ecc87d090f87
      • Whitelist Spark ALM Proxy on the PSM

      • IPSMLike(MCD_LITE_PSM_USDC_A).kiss(almProxy: 0x1601843c5E9bC251A3272907010AFa41Fa18347E);

      • Add new validators for Median (Medianizer)

        • Add ETH Global validator 0xcfC62b2269521e3212Ce1b6670caE6F0e34E8bF3 to the following median contracts

        • Add Mantle validator 0xFa6eb665e067759ADdE03a8E6bD259adBd1D70c9 to the following median contracts

        • Add Nethermind validator 0x91242198eD62F9255F2048935D6AFb0C2302D147 to the following median contracts

        • Add Euler validator 0x1DCB8CcC022938e102814F1A299C7ae48A8BAAf6to the following median contracts

        • Add all validators declared above to BTC/USD median contract at 0xe0F30cb149fAADC7247E953746Be9BbBB6B5751f

        • Add all validators declared above to ETH/USD median contract at 0x64DE91F5A373Cd4c28de3600cB34C7C6cE410C85

        • Add all validators declared above to WSTETH/USD median contract at 0x2F73b6567B866302e132273f67661fB89b5a66F2

        • Add all validators declared above to MKR/USD median contract at 0xdbBe5e9B1dAa91430cF0772fCEbe53F6c6f137DF

  • 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 to false
    • Office hours value matches the Exec Sheet
    • 30 days spell expiry set in the constructor (block.timestamp + 30 days)
  • 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)"
  • 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 and Authority 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 and Authority URL have prefix derived from the url itself
      • // Executive Vote: if URL starts with https://vote.makerdao.com/executive/
      • // Poll: if URL starts with https://vote.makerdao.com/polling/
      • // Forum: if URL starts with https://forum.makerdao.com/t/
      • // MIP: if URL starts with https://mips.makerdao.com/mips/details/
  • Dependency checks

    • Update Foundry by running foundryup
    • Reinstall libraries by running rm -rf ./lib && git submodule update --init --recursive
      Insert checked out submodule paths here
      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 'a8a7b151c39282d4ddab8cb4ead2d80342df588f'
      Submodule path 'lib/dss-test/lib/dss-interfaces': checked out '9bfd7afadd1f8c217ef05850b2555691786286cb'
      Submodule path 'lib/dss-test/lib/forge-std': checked out '978ac6fadb62f5f0b723c996f64be52eddba6801'
    • IF submodule upgrades are present, make sure dss-exec-lib is synced as well
    • git submodule hash of dss-exec-lib (run git submodule status) matches the latest release version or newer
    • dss-interfaces library used inside lib/dss-exec-lib matches submodule used inside lib/dss-test
  • 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";)
    • 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)
      • Each static interface declare only functions actually used in the spell code
  • 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
    • 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
    • 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
    • IF timestamps are present
      • Comment above timestamp states full date including UTC timezone
      • Timestamp converts back to the correct date
      • Timestamp converts back to the UTC timezone
      • Variable naming matches MMM_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 as internal
      • Each variable state mutability is declared as constant
  • IF new contract is present in the spell (not yet on chainlog or new to chainlog)

    • L1GovernanceRelay: 0x1Ee0AE8A993F2f5abDB51EAF4AC2876202b65c3b

    • 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol

    • Escrow: 0x7F311a4D48377030bD810395f4CCfC03bdbe9Ef3

    • 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol

    • ERC1967Proxy: 0xA5874756416Fa632257eEA380CAbd2E87cED352A

    • Source code is verified on etherscan

    • Compilation optimizations match deployment settings defined in the source code repo

    • GNU AGPLv3 license
      ℹ️ It uses the MIT 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 was relied (wards(PAUSE_PROXY) is 1)
      • ~~Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol

    • L1TokenBridge: 0xaeFd31c2e593Dc971f9Cb42cBbD5d4AD7F1970b6

    • 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
      ℹ️ It is done via its proxy

      • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol

    • L2GovernanceRelay: 0xdD0BCc201C9E47c6F6eE68E4dB05b652Bb6aC255

    • 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol
      ℹ️ It does not exist, but this ok since it is on Base L2.

    • ERC1967Proxy: 0xee44cdb68D618d58F75d9fe0818B640BD7B8A7B7

    • Source code is verified on etherscan

    • Compilation optimizations match deployment settings defined in the source code repo

    • GNU AGPLv3 license
      ℹ️ It uses the MIT 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol
      ℹ️ It does not exist, but this ok since it is on Base L2.

    • L2TokenBridge: 0x289A37BE5D6CCeF7A8f2b90535B3BB6bD3905f72

    • 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
      ℹ️ Done via Spell script and its proxy.

      • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol
      ℹ️ It does not exist, but this ok since it is on Base L2.

    • L2TokenBridgeSpell: 0x6f29C3A29A3F056A71FB0714551C8D3547268D62

    • 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol
      ℹ️ It does not exist, but this ok since it is on Base L2.

    • Allocator Oracle: 0xc7B91C401C02B73CBdF424dFaaa60950d5040dB7

    • 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol

    • AllocatorRoles: 0x9A865A710399cea85dbD9144b7a09C889e94E803

    • 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol

    • AllocatorRegistry: 0xCdCFA95343DA7821fdD01dc4d0AeDA958051bB3B

    • 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol

    • AllocatorBuffer: 0xc395D150e71378B47A1b8E9de0c1a83b75a08324

    • 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol

    • AllocatorVault: 0x691a6c29e9e96dd897718305427Ad5D534db16BA

    • 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 was relied (wards(PAUSE_PROXY) is 1)
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol

    • USDS Proxy: 0x820C137fa70C8691f0e44Dc420a5e53c168921Dc, Implementation: 0x191CD41681a3fE15aa15a0bec415821CE24CAd5e

    • Source code is verified on etherscan

    • Compilation optimizations match deployment settings defined in the source code repo

    • GNU AGPLv3 license
      ℹ️ The proxies have another license (MIT)

    • Every maker-related constructor argument matches chainlog (e.g. vat, dai, dog, ...)

    • IF new contract have concept of wards or access control
      ℹ️ Done via Proxy

      • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        ℹ️ Instead of PAUSE_PROXY, L2_BASE_GOV_RELAY (L2GovernanceRelay) was used for this
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
        ℹ️ Instead of PAUSE_PROXY, L2_BASE_GOV_RELAY (L2GovernanceRelay) was used for this
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol
      ℹ️ It does not exist, but this ok since it is on Base L2.

    • USDS Proxy: 0x5875eEE11Cf8398102FdAd704C9E96607675467a, Implementation: 0x982f2DF63Fe38AB8d55f4B1464e8cfDc8eA5dEC8

    • Source code is verified on etherscan

    • Compilation optimizations match deployment settings defined in the source code repo

    • GNU AGPLv3 license
      ℹ️ The proxies have another license (MIT)

    • Every maker-related constructor argument matches chainlog (e.g. vat, dai, dog, ...)

    • IF new contract have concept of wards or access control
      ℹ️ Done via Proxy

      • Ensure PAUSE_PROXY address was relied (wards(PAUSE_PROXY) is 1)
        ℹ️ Instead of PAUSE_PROXY, L2_BASE_GOV_RELAY (L2GovernanceRelay) was used for this
      • Ensure that contract deployer address was denied (wards(deployer) is 0)
      • Ensure that there are no other Rely events except for PAUSE_PROXY (using a block explorer like etherscan)
        ℹ️ Instead of PAUSE_PROXY, L2_BASE_GOV_RELAY (L2GovernanceRelay) was used for this
    • Source code matches corresponding github source code (e.g. diffcheck via vscode code --diff etherscan.sol github.sol)
      ℹ️ Done manually.

    • Deployer address is included into addresses_deployers.sol
      ℹ️ It does not exist, but this ok since it is on Base L2.

  • IF core system parameter changes are present in the instructions

  • IF debt ceiling changes are present in the instructions

  • 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
    • 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 onboarding is present

    • Insert and follow the relevant checklists below:

      Collateral Onboarding Checklist

      ℹ️ Not all checks apply in this case, thus they are omitted but assumed to be ok
    • 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)
          • 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)
      • 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 authed join access)
          • parameters are correct
            • owner matches MCD Pause Proxy
            • ilk is the bytes32 representation of "TOKEN-A"
              • cast --to-ascii <bytes32> matches ASCII Ilk
              • cast --to-bytes32 $(cast --from-ascii "TOKEN-A") matches bytes32
            • 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 the bytes32 representation of "TOKEN-A"
              • cast --to-ascii <bytes32> matches ASCII Ilk
              • cast --to-bytes32 $(cast --from-ascii "TOKEN-A") matches bytes32
      • Calc
        • deployed via CalcFab
          • Fab matches chainlog
          • newStairstepExponentialDecrease
          • newLinearDecrease
          • newExponentialDecrease
          • parameters are correct
            • owner matches MCD Pause Proxy
      • Risk Parameters
      • Autoline (setIlkAutoLineParameters)
        • ilk
        • line
        • gap
        • ttl
      • Onboarding Actions
        • ensure DssExecLib.addNewCollateral is used
          ℹ️ Not used, it is done via the init script dependency.
        • ensure CollateralOpts is used
          ℹ️ Not used (check step above)
          • ilk follows the ilk format TOKEN-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 IF pip is OSM
          • whitelistOSM set to true IF median is src in OSM
          • ilkDebtCeiling (vat.ilk.line) in DAI (e.g. 1 * MILLION)
            • IF autoline is enabled, vat.ilk.line should be set to DC-IAM gap value
          • minVaultAmount (vat.ilk.dust) in DAI (e.g. 15_000)
            • ensure clip.tip is adjusted proportionally to vat.ilk.dust (e.g. lower the dust lower the tip)
          • maxLiquidationAmount (dog.ilk.hole) in DAI (e.g. 5 * MILLION)
            • ensure dog.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 format TOKEN-A
          • linein DAI (e.g. 10 * MILLION)
          • gap in DAI (e.g. 1 * MILLION)
          • ttl in seconds (e.g. 8 hours)
      • New Chainlog Entries
        • TOKEN
        • PIP_TOKEN
        • MCD_JOIN_TOKEN_A
        • MCD_CLIP_TOKEN_A
        • MCD_CLIP_CALC_TOKEN_A
      • Chainlog Bump
        • Patch x.x.1
      • Test Coverage (Follow Previous Test Patterns)
        testChainlogIntegrity and ``
        • testCollateralIntegrations
          ℹ️ Not used, but tested in testAllocatorIntegration() instead
        • testNewChainlogValues
          ℹ️ Deprecated: tested via testChainlogIntegrity() and testChainlogValues()
        • testNewIlkRegistryValues
          ℹ️ Not used, but tested in testAllocatorIntegration() instead
        • 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
      • RWA Onboarding
      • Teleport Onboarding
  • IF PSM migration, onboarding or offboarding is present:

  • IF D3M onboarding is present, insert and follow D3M Checklist

  • IF collateral offboarding is present in the spell

    • 1st stage collateral offboarding
      • Collateral type (ilk) is removed from AutoLine (MCD_IAM_AUTO_LINE) IF currently enabled
      • Collateral debt ceiling (vat.ilk.line) is set to 0
      • Global debt ceiling (vat.Line) decreased by the total amount of offboarded ilks
    • 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 to 0 IF requested by governance
      • Flat keeper incentive (tip) is set to 0 IF requested by governance
      • Relative keeper incentive (chip) is set to 0 IF requested by governance
      • Max liquidation amount (hole) is adjusted via DssExecLib.setIlkMaxLiquidationAmount(ilk, amount) IF requested by governance
      • Relevant clipper contract (MCD_CLIP_) is active (i.e. stopped is 0)
      • Liquidations are triggered via (depending on governance instruction):
        • EITHER liquidation ratio (spotter.ilk.mat) being set very high in the spell (using DssExecLib.setValue(DssExecLib.spotter(), ilk, "mat", ratio))
        • OR via enabling linear interpolation (DssExecLib.linearInterpolation(name, target, ilk, what, startTime, start, end, duration))
          • Ensure name format matches "XXX-X Offboarding"
          • Ensure target matches DssExecLib.spotter() address
          • Ensure ilk format matches collateral type (ilk) name ("XXX-X")
          • Ensure what matches string "mat"
          • Ensure startTime matches block.timestamp
          • Ensure start uses variable CURRENT_XXX_A_MAT
          • Ensure start matches current spotter.ilk.mat value
          • Ensure end uses variable TARGET_XXX_A_MAT
          • Ensure end value matches the instruction
          • Ensure end allows liquidation of all remaining vaults (end is bigger than collateral_type_collateralization_ratio * risk_multiplier_factor)
          • Ensure duration matches the instruction
      • Spotter price is updated via DssExecLib.updateCollateralPrice(ilk) IF collateral have no running oracle (i.e. relevant PIP_ contract have outdated zzz value)
      • Spotter price is updated after all other actions
      • Offboarding is tested at least via _checkIlkClipper helper
  • IF RWA updates are present

    • IF doc is updated
      • _updateDoc helper is copied one-to-one from the archive and defined above actions
      • _updateDoc(ilk, doc) is called in the spell
    • IF debt ceiling is updated
      • IF AutoLine update is requested by the Exec Sheet
      • IF regular debt ceiling (vat.ilk.line) update is requested by the Exec Sheet
      • Liquidation oracle price is bumped via RwaLiquidationOracleLike(MIP21_LIQUIDATION_ORACLE).bump(ilk, val) pattern
        • Comment above bump explains val computation via // Note: the formula is: "debt_ceiling * [ (1 + rwa_stability_fee ) ^ (minimum_deal_duration_in_years) ] * liquidation_ratio"
        • Comment above bump 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 the val 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 existing val value can be retrieved by calling read() on PIP_RWAXX and converting the result into decimal
      • Oracle price is updated via DssExecLib.updateCollateralPrice(ilk)
      • IF soft liquidation explicitly requested to be triggered (via .tell(ilk)) AND debt ceiling is 0 (OR is being set to 0 in the current spell)
        • RwaLiquidationOracle.tell(ilk) call is present
        • IF RWAXX_A_INPUT_CONDUIT is an instance of TinlakeMgr (it is a Centrifuge integration), additional TinlakeMgr.tell() call is present (in order to prevent further TIN redemptions in the Centrifuge pool)
  • IF payments are present in the spell

    • IF MKR 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
      • Transfer amount is specified with (at least) 2 decimals using ether keyword
      • IF ether 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 via testMKRPayments test
      • Sum of all MKR transfers tested in testMKRPayments 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
      • Sum of all DAI transfers tested in testDAIPayments matches number in the Exec Sheet
    • IF MKR or DAI streams (DssVest) are created
      • VestAbstract interface is imported from dss-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 in addresses_wallets.sol
      • tot (Total stream amount) matches Exec Sheet
      • IF ether 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 as bgn - fin (i.e. MONTH_DD_YYYY - MONTH_DD_YYYY)
      • fin (Vest end timestamp) matches Exec Sheet
      • eta (Vest cliff duration) matches the following logic
        • IF eta is explicitly specified in the Exec Sheet, then the values match
        • IF eta and clf (Cliff end timestamp) are not specified in the Exec Sheet, then eta is 0
        • IF clf is specified, but clf <= bgn, then eta is 0
        • IF clf is specified and clf > bgn, eta is expressed as clf - bgn (i.e. MONTH_DD_YYYY - MONTH_DD_YYYY)
      • IF mgr (Vest manager address) is specified in the Exec Sheet, matches the value, OTHERWISE matches address(0)
      • Ensure that max vesting rate (cap) is enough for the new streams
        • The maximum vesting rate (tot divided by tau) <= the maximum vest streaming rate (cap)
        • The maximum vesting rate (tot divided by tau) > the maximum vest streaming rate (cap)
        • Calculate new cap value equal to 10% greater than the new maximum vesting rate, then round new cap 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 cumulative total (the sum of all tot values)
        • Ensure allowance increase follows archive patterns
      • Tested via testVestDAI or testVestMKR
    • IF MKR or DAI vest termination (Yank) is present
      • Yanked stream ID matches Exec Sheet
      • MCD_VEST_MKR_TREASURY chainlog address is used for MKR stream yank
      • MCD_VEST_DAI chainlog address is used for DAI stream yank
      • Tested via testYankDAI or testYankMKR
  • 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
      • 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 Proxy DelegateCall context)
      • No SubDAO contract being interacted with is authed on a core contract like vat, 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 the PAUSE_PROXY as their admin (i.e. the party that can upgrade)
        • Any upgradable SubDAO contracts with an admin that is not PAUSE_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 external contracts calls are present (Not SubDAOs, e.g. Starknet)

    • Target Contract doesn't block spell execution
    • External call is NOT delegatecall
    • Target Contract doesn't have permissions on the Vat
    • Target Contract doesn't do anything untoward (e.g. interacting with unsafe contracts)
    • Contracts deployed via CREATE2 (e.g. if it looks like a vanity address) do not have selfdestruct 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 and testChainlogValues
  • Ensure every spell variable is declared as public/internal

  • Ensure immutable visibility is only used when fetching addresses from the ChainLog via DssExecLib.getChangelogAddress(key) and constant is used instead for static addresses

    • Fetch addresses as type address and wrap with Like suffix interfaces inline (when making calls), UNLESS archive patterns permit otherwise (Such as MKR)
    • 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 than vat), except where the archive pattern differs from this pattern (e.g. MKR)
  • 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
      Insert most recent commit hash where CI was passing
      57a5fb7
    • 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 the skipped modifier
    • Ensure each spell action has sufficient test coverage
      List actions for which coverage was checked here
      [x] Init Base Native Bridge
      testBaseTokenBridgeIntegration
      [x] Init Allocator System for Spark Subdao Proxy
      testAllocatorIntegration(), testGeneral() and editing config.sol properly
      [x] Whitelist Spark ALM Proxy on the PSM
      testsWhitelistSparkProxyOnLitePsm()
      [x] Add new validators for Median
      testMedianValidators()
      [x] Bump chainlog version and chainlog additions
      testChainlogIntegrity() & testChainlogValues()
    • 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.
_Insert your local test logs here_
./scripts/test-dssspell-forge.sh no-match="" match="" block=""
Using DssExecLib at: 0x8De6DDbCd5053d32292AAA0D2105A32d108484a6
[⠊] Compiling...
[⠰] Compiling 43 files with Solc 0.8.16
[⠔] Solc 0.8.16 finished in 10.74s
Compiler run successful with warnings:
Warning (2018): Function state mutability can be restricted to view
   --> src/DssSpell.t.base.sol:983:5:
    |
983 |     function _getOSMPrice(address pip) internal returns (uint256) {
    |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to view
   --> src/DssSpell.t.base.sol:999:5:
    |
999 |     function _getUNIV2LPPrice(address pip) internal returns (uint256) {
    |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to pure
    --> src/DssSpell.t.base.sol:2174:5:
     |
2174 |     function _getSignatures(bytes32 signHash) internal returns (bytes memory signatures, address[] memory signers) {
     |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to view
    --> src/DssSpell.t.base.sol:2366:5:
     |
2366 |     function _checkTransferrableVestMkrAllowance() internal {
     |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to view
    --> src/DssSpell.t.base.sol:2722:5:
     |
2722 |     function _testContractSize() internal {
     |     ^ (Relevant source part starts here and spans across multiple lines).


Ran 2 tests for src/test/starknet.t.sol:StarknetTests
[PASS] testStarknet() (gas: 3063995)
[PASS] testStarknetSpell() (gas: 2287)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 44.69s (38.77s CPU time)

Warning: the following cheatcode(s) are deprecated and will be removed in future versions:
  revertTo(uint256): replaced by `revertToState`
  snapshot(): replaced by `snapshotState`
Ran 42 tests for src/DssSpell.t.sol:DssSpellTest
[PASS] testAllocatorIntegration() (gas: 3236363)
[PASS] testBaseTokenBridgeIntegration() (gas: 302351004)
[SKIP] testBytecodeMatches() (gas: 0)
[PASS] testCastCost() (gas: 2922166)
[PASS] testCastOnTime() (gas: 2918366)
[PASS] testChainlogIntegrity() (gas: 8403472)
[PASS] testChainlogValues() (gas: 10904791)
[SKIP] testCollateralIntegrations() (gas: 0)
[PASS] testContractSize() (gas: 14897)
[SKIP] testDaoResolutions() (gas: 0)
[PASS] testDeployCost() (gas: 3347458)
[SKIP] testEsmAuth() (gas: 0)
[PASS] testGeneral() (gas: 29135134)
[SKIP] testIlkClipper() (gas: 0)
[SKIP] testL2ArbitrumSpell() (gas: 0)
[SKIP] testL2OptimismSpell() (gas: 0)
[SKIP] testLerpSurplusBuffer() (gas: 0)
[PASS] testLitePSMs() (gas: 3820926)
[SKIP] testLockstakeIlkIntegration() (gas: 0)
[SKIP] testMedianReaders() (gas: 0)
[PASS] testMedianValidators() (gas: 2967983)
[SKIP] testNewAuthorizations() (gas: 0)
[SKIP] testNewCronJobs() (gas: 0)
[PASS] testNextCastTime() (gas: 344159)
[SKIP] testOffboardings() (gas: 0)
[PASS] testOfficeHours() (gas: 15597)
[SKIP] testOracleList() (gas: 0)
[SKIP] testOsmReaders() (gas: 0)
[PASS] testPSMs() (gas: 4123208)
[SKIP] testPayments() (gas: 0)
[SKIP] testRemoveChainlogValues() (gas: 0)
[PASS] testRevertIfNotScheduled() (gas: 16808)
[SKIP] testSparkSpellIsExecuted() (gas: 0)
[PASS] testSplitter() (gas: 3522653)
[PASS] testSystemTokens() (gas: 4007583)
[PASS] testUseEta() (gas: 343170)
[SKIP] testVestDAI() (gas: 0)
[SKIP] testVestMKR() (gas: 0)
[SKIP] testVestSKY() (gas: 0)
[SKIP] testYankDAI() (gas: 0)
[SKIP] testYankMKR() (gas: 0)
[PASS] testsWhitelistSparkProxyOnLitePsm() (gas: 2921194)
Suite result: ok. 19 passed; 0 failed; 23 skipped; finished in 416.60s (1209.48s CPU time)

Ran 2 test suites in 417.68s (461.29s CPU time): 21 tests passed, 0 failed, 23 skipped (44 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
      Insert your Raw Exec Doc URL here
      https://raw.githubusercontent.com/makerdao/community/820339cf860e625924811f181062851d7e25b610/governance/votes/Executive%20vote%20-%20October%2031%2C%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>"
        
        Output:
        820339cf860e625924811f181062851d7e25b610 Adding Ecosystem Approvals```
        
    • Using Exec Doc URL from the above and the TARGET_DATE, generate Exec Doc Hash via make exec-hash date=$TARGET_DATE $URL
      Insert your Exec Doc Hash here
      0x6407f9203bf4f816cc353ebc95463d917e77ccb701f2e85945dcf91274b628ed
    • Using Exec Doc URL from the above, generate Exec Doc Hash via cast keccak -- "$(curl '$URL' -o - 2>/dev/null)"
      Insert your Exec Doc Hash here
      0x6407f9203bf4f816cc353ebc95463d917e77ccb701f2e85945dcf91274b628ed
    • 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
      List all instructions announced in the Exec Doc
      • Base Network SkyLink Bridge Initialization for USDS and sUSDS
        The Base Network SkyLink bridge for USDS and sUSDS will be initialized by calling TokenBridgeInit.initBridges with its parameters set as follows:

        • l1BridgeInstance:

          • govRelay: 0x1Ee0AE8A993F2f5abDB51EAF4AC2876202b65c3b
          • escrow: 0x7F311a4D48377030bD810395f4CCfC03bdbe9Ef3
          • bridge: 0xA5874756416Fa632257eEA380CAbd2E87cED352A
          • bridgeImp: 0xaeFd31c2e593Dc971f9Cb42cBbD5d4AD7F1970b6
          • l2BridgeInstance:
          • govRelay: 0xdD0BCc201C9E47c6F6eE68E4dB05b652Bb6aC255
          • bridge: 0xee44cdb68D618d58F75d9fe0818B640BD7B8A7B7
          • bridgeImp: 0x289A37BE5D6CCeF7A8f2b90535B3BB6bD3905f72
          • spell: 0x6f29C3A29A3F056A71FB0714551C8D3547268D62
        • cfg:

          • l1Messenger: 0x866E82a600A1414e583f7F13623F1aC5d58b0Afa
          • l2Messenger: 0x4200000000000000000000000000000000000007
          • l1Tokens:
          • 0xdc035d45d973e3ec169d2276ddab16f1e407384f (USDS on Mainnet)
          • 0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD (sUSDS on Mainnet)
          • l2Tokens:
          • 0x820C137fa70C8691f0e44Dc420a5e53c168921Dc (USDS on Base)
          • 0x5875eEE11Cf8398102FdAd704C9E96607675467a (sUSDS on Base)
          • maxWithdraws: type(uint256).max for each token
          • minGasLimit: 500,000
          • govRelayCLKey: BASE_GOV_RELAY (chainlog key for govRelay)
          • escrowCLKey: BASE_ESCROW (chainlog key for Escrow)
          • l1BridgeCLKey: BASE_TOKEN_BRIDGE (chainlog key for L1TokenBridge)
          • l1BridgeImpCLKey: BASE_TOKEN_BRIDGE_IMP (chainlog key for L1TokenBridgeImp)
      • Star Allocation System Initialization for Spark
        The Star Allocation System for Spark will be initialized by executing the actions below:

        • Initialize shared components for the Allocator System by calling AllocatorInit.initShared with the following parameters:
          • oracle: 0xc7B91C401C02B73CBdF424dFaaa60950d5040dB7 (AllocatorOracle)
          • roles: 0x9A865A710399cea85dbD9144b7a09C889e94E803 (AllocatorRoles)
          • registry: 0xCdCFA95343DA7821fdD01dc4d0AeDA958051bB3B (AllocatorRegistry)
        • Initialize Allocator ILK for Spark Star by calling AllocatorInit.initIlk with its parameters set as follow:
          • sharedInstance:
            • oracle: 0xc7B91C401C02B73CBdF424dFaaa60950d5040dB7 (AllocatorOracle)
            • roles: 0x9A865A710399cea85dbD9144b7a09C889e94E803 (AllocatorRoles)
            • registry: 0xCdCFA95343DA7821fdD01dc4d0AeDA958051bB3B (AllocatorRegistry)
          • ilkInstance:
            • owner: 0xbe8e3e3618f7474f8cb1d074a26affef007e98fb (MCD_PAUSE_PROXY)
            • vault: 0x691a6c29e9e96dd897718305427Ad5D534db16BA (AllocatorVault)
            • buffer: 0xc395D150e71378B47A1b8E9de0c1a83b75a08324 (AllocatorBuffer)
          • cfg:
            • ilk: ALLOCATOR-SPARK-A
            • duty: 1000000001607468111246255079 (5.2%)
            • gap: 10,000,000 DAI
            • maxLine: 10,000,000 DAI
            • ttl: 86,400 seconds
            • allocatorProxy: 0x3300f198988e4C9C63F75dF86De36421f06af8c4 (SparkProxy)
            • ilkRegistry: 0x5a464c28d19848f44199d003bef5ecc87d090f87
      • Whitelist Spark ALM Proxy on the LitePSM by calling IPSMLike(MCD_LITE_PSM_USDC_A).kiss(almProxy: 0x1601843c5E9bC251A3272907010AFa41Fa18347E).

      • Add new validators for Median (Medianizer)
        All validators below:

        • ETH Global validator - 0xcfC62b2269521e3212Ce1b6670caE6F0e34E8bF3
        • Mantle validator - 0xFa6eb665e067759ADdE03a8E6bD259adBd1D70c9
        • Nethermind validator - 0x91242198eD62F9255F2048935D6AFb0C2302D147
        • Euler validator - 0x1DCB8CcC022938e102814F1A299C7ae48A8BAAf6

        will be added to each of the median contracts below:

        • BTC/USD at 0xe0F30cb149fAADC7247E953746Be9BbBB6B5751f
        • ETH/USD at 0x64DE91F5A373Cd4c28de3600cB34C7C6cE410C85
        • WSTETH/USD at 0x2F73b6567B866302e132273f67661fB89b5a66F2
        • MKR/USD at 0xdbBe5e9B1dAa91430cF0772fCEbe53F6c6f137DF
    • Office hours value in the Exec Doc matches the spell
      ℹ️ There is no office hours reference, assumed to be No which is validated by the Exec Sheet
    • 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
  • 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

@0xdecr1pto

This comment was marked as outdated.

@SidestreamStrongStrawberry
Copy link
Collaborator

Good to deploy

  • IF new commits are present in the spell
    • Copy relevant checklist items from the above and redo them
      ℹ️ Only the state variable order has been changed for re-verifying the source code on etherscan
    • Ensure newly added code is covered by tests
    • Check if chainlog needs to be updated
    • Copy over and redo "Tests" section from the above
    • 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
        Insert most recent commit hash where CI was passing
        88207c7
      • 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 the skipped modifier
      • Ensure each spell action has sufficient test coverage
        List actions for which coverage was checked here
        • Init Base Native Bridge
          • Init Base Token Bridge for USDS, sUSDS by calling TokenBridgeInit.initBridges using the following parameters:
            • tested via testBaseTokenBridgeIntegration, testChainlogIntegrity and testChainlogValues
        • Init Allocator System for Spark Subdao Proxy
          • Init shared components for Allocator System be calling AllocatorInit.initShared
            • tested via testChainlogIntegrity and testChainlogValues
          • Init Allocator ILK for Spark Subdao by calling AllocatorInit.initIlk using the following parameters:
            • tested via testAllocatorIntegration and testGeneral
        • Whitelist Spark ALM Proxy on the PSM
          • tested via testsWhitelistSparkProxyOnLitePsm
        • Add new validators for Median (Medianizer)
          • tested via testMedianValidators
        • Add all validators declared above to BTC/USD median contract at 0xe0F30cb149fAADC7247E953746Be9BbBB6B5751f
          • tested via testMedianValidators
      • 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.
      _Insert your local test logs here_
      ./scripts/test-dssspell-forge.sh no-match="" match="" block=""
      Using DssExecLib at: 0x8De6DDbCd5053d32292AAA0D2105A32d108484a6
      [⠊] Compiling...
      No files changed, compilation skipped
      
      Ran 2 tests for src/test/starknet.t.sol:StarknetTests
      [PASS] testStarknet() (gas: 2990379)
      [PASS] testStarknetSpell() (gas: 2287)
      Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 42.14s (38.43s 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 42 tests for src/DssSpell.t.sol:DssSpellTest
      [PASS] testAllocatorIntegration() (gas: 3162747)
      [PASS] testBaseTokenBridgeIntegration() (gas: 302021624)
      [SKIP] testBytecodeMatches() (gas: 0)
      [PASS] testCastCost() (gas: 2848550)
      [PASS] testCastOnTime() (gas: 2844750)
      [PASS] testChainlogIntegrity() (gas: 8329856)
      [PASS] testChainlogValues() (gas: 10831175)
      [SKIP] testCollateralIntegrations() (gas: 0)
      [PASS] testContractSize() (gas: 14897)
      [SKIP] testDaoResolutions() (gas: 0)
      [PASS] testDeployCost() (gas: 3347458)
      [SKIP] testEsmAuth() (gas: 0)
      [PASS] testGeneral() (gas: 29061518)
      [SKIP] testIlkClipper() (gas: 0)
      [SKIP] testL2ArbitrumSpell() (gas: 0)
      [SKIP] testL2OptimismSpell() (gas: 0)
      [SKIP] testLerpSurplusBuffer() (gas: 0)
      [PASS] testLitePSMs() (gas: 3687212)
      [SKIP] testLockstakeIlkIntegration() (gas: 0)
      [SKIP] testMedianReaders() (gas: 0)
      [PASS] testMedianValidators() (gas: 2894367)
      [SKIP] testNewAuthorizations() (gas: 0)
      [SKIP] testNewCronJobs() (gas: 0)
      [PASS] testNextCastTime() (gas: 344159)
      [SKIP] testOffboardings() (gas: 0)
      [PASS] testOfficeHours() (gas: 15597)
      [SKIP] testOracleList() (gas: 0)
      [SKIP] testOsmReaders() (gas: 0)
      [PASS] testPSMs() (gas: 4049592)
      [SKIP] testPayments() (gas: 0)
      [SKIP] testRemoveChainlogValues() (gas: 0)
      [PASS] testRevertIfNotScheduled() (gas: 16808)
      [SKIP] testSparkSpellIsExecuted() (gas: 0)
      [PASS] testSplitter() (gas: 3449037)
      [PASS] testSystemTokens() (gas: 3933967)
      [PASS] testUseEta() (gas: 343170)
      [SKIP] testVestDAI() (gas: 0)
      [SKIP] testVestMKR() (gas: 0)
      [SKIP] testVestSKY() (gas: 0)
      [SKIP] testYankDAI() (gas: 0)
      [SKIP] testYankMKR() (gas: 0)
      [PASS] testsWhitelistSparkProxyOnLitePsm() (gas: 2847578)
      Suite result: ok. 19 passed; 0 failed; 23 skipped; finished in 373.53s (933.77s CPU time)
      
      Ran 2 test suites in 374.04s (415.67s CPU time): 21 tests passed, 0 failed, 23 skipped (44 total tests)
      
  • IF all checks pass, make sure to include explicit "Good to deploy" comment

@0xp3th1um
Copy link
Collaborator

Good to deploy!!!

  • IF new commits are present in the spell
    • Copy relevant checklist items from the above and redo them
      ℹ️ There is no new functionality added, just a reordering of variables
    • Ensure newly added code is covered by tests
      ℹ️ There is no new functionality added, just a reordering of variables
    • Check if chainlog needs to be updated
    • Copy over and redo "Tests" section from the above
    • 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
      Insert most recent commit hash where CI was passing
      88207c7
    • 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 the skipped modifier
    • Ensure each spell action has sufficient test coverage
      List actions for which coverage was checked here
      [x] Init Base Native Bridge
      testBaseTokenBridgeIntegration
      [x] Init Allocator System for Spark Subdao Proxy
      testAllocatorIntegration(), testGeneral() and editing config.sol properly
      [x] Whitelist Spark ALM Proxy on the PSM
      testsWhitelistSparkProxyOnLitePsm()
      [x] Add new validators for Median
      testMedianValidators()
      [x] Bump chainlog version and chainlog additions
      testChainlogIntegrity() & testChainlogValues()
    • 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.
_Insert your local test logs here_
./scripts/test-dssspell-forge.sh no-match="" match="" block=""
Using DssExecLib at: 0x8De6DDbCd5053d32292AAA0D2105A32d108484a6
[⠊] Compiling...
[⠢] Compiling 5 files with Solc 0.8.16
[⠰] Solc 0.8.16 finished in 10.63s
Compiler run successful with warnings:
Warning (2018): Function state mutability can be restricted to view
   --> src/DssSpell.t.base.sol:983:5:
    |
983 |     function _getOSMPrice(address pip) internal returns (uint256) {
    |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to view
   --> src/DssSpell.t.base.sol:999:5:
    |
999 |     function _getUNIV2LPPrice(address pip) internal returns (uint256) {
    |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to pure
    --> src/DssSpell.t.base.sol:2174:5:
     |
2174 |     function _getSignatures(bytes32 signHash) internal returns (bytes memory signatures, address[] memory signers) {
     |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to view
    --> src/DssSpell.t.base.sol:2366:5:
     |
2366 |     function _checkTransferrableVestMkrAllowance() internal {
     |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to view
    --> src/DssSpell.t.base.sol:2722:5:
     |
2722 |     function _testContractSize() internal {
     |     ^ (Relevant source part starts here and spans across multiple lines).


Ran 2 tests for src/test/starknet.t.sol:StarknetTests
[PASS] testStarknet() (gas: 2993475)
[PASS] testStarknetSpell() (gas: 2287)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 53.13s (46.29s 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 42 tests for src/DssSpell.t.sol:DssSpellTest
[PASS] testAllocatorIntegration() (gas: 3165843)
[PASS] testBaseTokenBridgeIntegration() (gas: 302048972)
[SKIP] testBytecodeMatches() (gas: 0)
[PASS] testCastCost() (gas: 2851646)
[PASS] testCastOnTime() (gas: 2847846)
[PASS] testChainlogIntegrity() (gas: 8332952)
[PASS] testChainlogValues() (gas: 10834271)
[SKIP] testCollateralIntegrations() (gas: 0)
[PASS] testContractSize() (gas: 14897)
[SKIP] testDaoResolutions() (gas: 0)
[PASS] testDeployCost() (gas: 3347458)
[SKIP] testEsmAuth() (gas: 0)
[PASS] testGeneral() (gas: 29064614)
[SKIP] testIlkClipper() (gas: 0)
[SKIP] testL2ArbitrumSpell() (gas: 0)
[SKIP] testL2OptimismSpell() (gas: 0)
[SKIP] testLerpSurplusBuffer() (gas: 0)
[PASS] testLitePSMs() (gas: 3690308)
[SKIP] testLockstakeIlkIntegration() (gas: 0)
[SKIP] testMedianReaders() (gas: 0)
[PASS] testMedianValidators() (gas: 2897463)
[SKIP] testNewAuthorizations() (gas: 0)
[SKIP] testNewCronJobs() (gas: 0)
[PASS] testNextCastTime() (gas: 344159)
[SKIP] testOffboardings() (gas: 0)
[PASS] testOfficeHours() (gas: 15597)
[SKIP] testOracleList() (gas: 0)
[SKIP] testOsmReaders() (gas: 0)
[PASS] testPSMs() (gas: 4052688)
[SKIP] testPayments() (gas: 0)
[SKIP] testRemoveChainlogValues() (gas: 0)
[PASS] testRevertIfNotScheduled() (gas: 16808)
[SKIP] testSparkSpellIsExecuted() (gas: 0)
[PASS] testSplitter() (gas: 3452133)
[PASS] testSystemTokens() (gas: 3937301)
[PASS] testUseEta() (gas: 343170)
[SKIP] testVestDAI() (gas: 0)
[SKIP] testVestMKR() (gas: 0)
[SKIP] testVestSKY() (gas: 0)
[SKIP] testYankDAI() (gas: 0)
[SKIP] testYankMKR() (gas: 0)
[PASS] testsWhitelistSparkProxyOnLitePsm() (gas: 2850674)
Suite result: ok. 19 passed; 0 failed; 23 skipped; finished in 470.34s (1373.05s CPU time)

Ran 2 test suites in 471.28s (523.47s CPU time): 21 tests passed, 0 failed, 23 skipped (44 total tests)
  • IF all checks pass, make sure to include explicit "Good to deploy" comment

@0xdecr1pto
Copy link
Contributor Author

@0xp3th1um
Copy link
Collaborator

Good to handover!

Deployed Stage

  • Source code settings
    • Deployed spell is verified on etherscan
    • Optimization enabled: false UNLESS the contract size is too big AND all mitigation strategies (i.e.: removing revert strings) have failed
      ℹ️ Optimization is enabled due to the spell's size.
    • Default evmVersion
    • GNU AGPLv3 license
  • Source code validity
    • Deployed spell code matches source on github. (can be checked via make diff-deployed-spell or manually)
      ℹ️ Checked manually as the addition of libraries makes the script report mismatches!
    • No new changes are made after previously given "good to deploy"
  • Deployed spell Etherscan checks
    • Automated checks via make check-deployed-spell
      • Verified
      • Valid license
      • Version matches
      • Optimizations are disabled
        ℹ️ Optimization is enabled due to the spell's size.
      • dss-exec-lib library address used (under 'Libraries Used') matches the hardcoded local DssExecLib.address file
      • deployed_spell_created matches deployment timestamp
      • deployed_spell_block matches deployment block number
    • Manual checks
      • Ensure make deploy-info tx=<tx> matches config
        • deployed_spell_created timestamp
          ℹ️ timestamp: 1730395583
        • deployed_spell_block block number
          ℹ️ block: 21087106
      • Check again that the PR did not modify the DssExecLib.address file (e.g. look under the 'Files Changed' PR tab, etc.)
      • Ensure Etherscan Libraries Used matches DssExecLib Latest Release
      • (For your tests to be accurate) git submodule hash matches dss-exec-lib latest release's tag commit and inspect diffs if doesn't match to ensure expected behaviour (Currently Non-Critical pending the next DssExecLib release, double check that the ExecLib used by the contract matches the latest release)
  • Tenderly Testnet checks
    • A testnet with the name matching spell description is found at maker dashboard
    • The testnet name is unique (previous testnets does not have the same name)
    • Cast transaction is set to the correct "receiver" (matches deployed spell address)
    • All actions are executed in the transaction trace
    • No reverts are present that block execution
    • No out-of-gas errors are present
  • Archive checks
    • make diff-archive-spell for current date or make diff-archive-spell date="YYYY-MM-DD"
    • Ensure date corresponds to target Exec Doc date
  • 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
      Insert most recent commit hash where CI was passing
      4e44a95
    • 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
./scripts/test-dssspell-forge.sh no-match="" match="" block=""
Using DssExecLib at: 0x8De6DDbCd5053d32292AAA0D2105A32d108484a6
[⠊] Compiling...
[⠆] Compiling 4 files with Solc 0.8.16
[⠰] Solc 0.8.16 finished in 10.72s
Compiler run successful with warnings:
Warning (2018): Function state mutability can be restricted to view
   --> src/DssSpell.t.base.sol:983:5:
    |
983 |     function _getOSMPrice(address pip) internal returns (uint256) {
    |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to view
   --> src/DssSpell.t.base.sol:999:5:
    |
999 |     function _getUNIV2LPPrice(address pip) internal returns (uint256) {
    |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to pure
    --> src/DssSpell.t.base.sol:2174:5:
     |
2174 |     function _getSignatures(bytes32 signHash) internal returns (bytes memory signatures, address[] memory signers) {
     |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to view
    --> src/DssSpell.t.base.sol:2366:5:
     |
2366 |     function _checkTransferrableVestMkrAllowance() internal {
     |     ^ (Relevant source part starts here and spans across multiple lines).

Warning (2018): Function state mutability can be restricted to view
    --> src/DssSpell.t.base.sol:2722:5:
     |
2722 |     function _testContractSize() internal {
     |     ^ (Relevant source part starts here and spans across multiple lines).


Ran 2 tests for src/test/starknet.t.sol:StarknetTests
[PASS] testStarknet() (gas: 2999495)
[PASS] testStarknetSpell() (gas: 2287)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 50.02s (45.30s CPU time)

Warning: the following cheatcode(s) are deprecated and will be removed in future versions:
  revertTo(uint256): replaced by `revertToState`
  snapshot(): replaced by `snapshotState`
Ran 42 tests for src/DssSpell.t.sol:DssSpellTest
[PASS] testAllocatorIntegration() (gas: 3171863)
[PASS] testBaseTokenBridgeIntegration() (gas: 302061700)
[PASS] testBytecodeMatches() (gas: 3368098)
[PASS] testCastCost() (gas: 2857666)
[PASS] testCastOnTime() (gas: 2853866)
[PASS] testChainlogIntegrity() (gas: 8338972)
[PASS] testChainlogValues() (gas: 10840291)
[SKIP] testCollateralIntegrations() (gas: 0)
[SKIP] testContractSize() (gas: 0)
[SKIP] testDaoResolutions() (gas: 0)
[SKIP] testDeployCost() (gas: 0)
[SKIP] testEsmAuth() (gas: 0)
[PASS] testGeneral() (gas: 29072727)
[SKIP] testIlkClipper() (gas: 0)
[SKIP] testL2ArbitrumSpell() (gas: 0)
[SKIP] testL2OptimismSpell() (gas: 0)
[SKIP] testLerpSurplusBuffer() (gas: 0)
[PASS] testLitePSMs() (gas: 3696328)
[SKIP] testLockstakeIlkIntegration() (gas: 0)
[SKIP] testMedianReaders() (gas: 0)
[PASS] testMedianValidators() (gas: 2903483)
[SKIP] testNewAuthorizations() (gas: 0)
[SKIP] testNewCronJobs() (gas: 0)
[PASS] testNextCastTime() (gas: 344159)
[SKIP] testOffboardings() (gas: 0)
[PASS] testOfficeHours() (gas: 15597)
[SKIP] testOracleList() (gas: 0)
[SKIP] testOsmReaders() (gas: 0)
[PASS] testPSMs() (gas: 4058708)
[SKIP] testPayments() (gas: 0)
[SKIP] testRemoveChainlogValues() (gas: 0)
[PASS] testRevertIfNotScheduled() (gas: 16808)
[SKIP] testSparkSpellIsExecuted() (gas: 0)
[PASS] testSplitter() (gas: 3458153)
[PASS] testSystemTokens() (gas: 3943202)
[PASS] testUseEta() (gas: 343170)
[SKIP] testVestDAI() (gas: 0)
[SKIP] testVestMKR() (gas: 0)
[SKIP] testVestSKY() (gas: 0)
[SKIP] testYankDAI() (gas: 0)
[SKIP] testYankMKR() (gas: 0)
[PASS] testsWhitelistSparkProxyOnLitePsm() (gas: 2856694)
Suite result: ok. 18 passed; 0 failed; 24 skipped; finished in 456.93s (1343.17s CPU time)

Ran 2 test suites in 457.57s (506.95s CPU time): 20 tests passed, 0 failed, 24 skipped (44 total tests)

@SidestreamStrongStrawberry
Copy link
Collaborator

Good to handover :)

Deployed Stage

  • Source code settings
    • Deployed spell is verified on etherscan
    • Optimization enabled: false UNLESS the contract size is too big AND all mitigation strategies (i.e.: removing revert strings) have failed
    • Default evmVersion
    • GNU AGPLv3 license
  • Source code validity
    • Deployed spell code matches source on github. (can be checked via make diff-deployed-spell or manually)
    • No new changes are made after previously given "good to deploy"
  • Deployed spell Etherscan checks
    • Automated checks via make check-deployed-spell
      • Verified
        ⚠️ The script throws error but manual check matches
      • Valid license
        ⚠️ The script throws error but manual check matches
      • Version matches
        ⚠️ The script throws error but manual check matches
      • Optimizations are disabled
        ⚠️ Due to the size of the contract optimization is enabled and it is expected
      • dss-exec-lib library address used (under 'Libraries Used') matches the hardcoded local DssExecLib.address file
        ⚠️ The script throws error but manual check matches
      • deployed_spell_created matches deployment timestamp
        ⚠️ The script throws error but manual check matches
      • deployed_spell_block matches deployment block number
        ⚠️ The script throws error but manual check matches
    • Manual checks
      • Ensure make deploy-info tx=<tx> matches config
        • deployed_spell_created timestamp
        • deployed_spell_block block number
      • Check again that the PR did not modify the DssExecLib.address file (e.g. look under the 'Files Changed' PR tab, etc.)
      • Ensure Etherscan Libraries Used matches DssExecLib Latest Release
      • (For your tests to be accurate) git submodule hash matches dss-exec-lib latest release's tag commit and inspect diffs if doesn't match to ensure expected behaviour (Currently Non-Critical pending the next DssExecLib release, double check that the ExecLib used by the contract matches the latest release)
        ⚠️ The hash doesn't match as in the previous spells.
        Hash of latest release v0.0.9: c0d3c6c6244468ddab9767de6f853122723fafda
        git submodule lib/dss-exec-lib: 69b658f35d8618272cd139dfc18c5713caf6b96b
        diff check: changes are not related to current spell
  • Tenderly Testnet checks
    • A testnet with the name matching spell description is found at maker dashboard
    • The testnet name is unique (previous testnets does not have the same name)
    • Cast transaction is set to the correct "receiver" (matches deployed spell address)
    • All actions are executed in the transaction trace
    • No reverts are present that block execution
    • No out-of-gas errors are present
  • Archive checks
    • make diff-archive-spell for current date or make diff-archive-spell date="YYYY-MM-DD"
    • Ensure date corresponds to target Exec Doc date
  • 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
      Insert most recent commit hash where CI was passing
      4e44a95
    • 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
_Insert your local test logs here_
./scripts/test-dssspell-forge.sh no-match="" match="" block=""
Using DssExecLib at: 0x8De6DDbCd5053d32292AAA0D2105A32d108484a6
[⠊] Compiling...
No files changed, compilation skipped

Ran 2 tests for src/test/starknet.t.sol:StarknetTests
[PASS] testStarknet() (gas: 3015319)
[PASS] testStarknetSpell() (gas: 2287)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 44.46s (41.96s CPU time)

Warning: the following cheatcode(s) are deprecated and will be removed in future versions:
  revertTo(uint256): replaced by `revertToState`
  snapshot(): replaced by `snapshotState`
Ran 42 tests for src/DssSpell.t.sol:DssSpellTest
[PASS] testAllocatorIntegration() (gas: 3187687)
[PASS] testBaseTokenBridgeIntegration() (gas: 302153376)
[PASS] testBytecodeMatches() (gas: 3368098)
[PASS] testCastCost() (gas: 2873490)
[PASS] testCastOnTime() (gas: 2869690)
[PASS] testChainlogIntegrity() (gas: 8354796)
[PASS] testChainlogValues() (gas: 10856115)
[SKIP] testCollateralIntegrations() (gas: 0)
[SKIP] testContractSize() (gas: 0)
[SKIP] testDaoResolutions() (gas: 0)
[SKIP] testDeployCost() (gas: 0)
[SKIP] testEsmAuth() (gas: 0)
[PASS] testGeneral() (gas: 29088551)
[SKIP] testIlkClipper() (gas: 0)
[SKIP] testL2ArbitrumSpell() (gas: 0)
[SKIP] testL2OptimismSpell() (gas: 0)
[SKIP] testLerpSurplusBuffer() (gas: 0)
[PASS] testLitePSMs() (gas: 3712152)
[SKIP] testLockstakeIlkIntegration() (gas: 0)
[SKIP] testMedianReaders() (gas: 0)
[PASS] testMedianValidators() (gas: 2919307)
[SKIP] testNewAuthorizations() (gas: 0)
[SKIP] testNewCronJobs() (gas: 0)
[PASS] testNextCastTime() (gas: 344159)
[SKIP] testOffboardings() (gas: 0)
[PASS] testOfficeHours() (gas: 15597)
[SKIP] testOracleList() (gas: 0)
[SKIP] testOsmReaders() (gas: 0)
[PASS] testPSMs() (gas: 4074532)
[SKIP] testPayments() (gas: 0)
[SKIP] testRemoveChainlogValues() (gas: 0)
[PASS] testRevertIfNotScheduled() (gas: 16808)
[SKIP] testSparkSpellIsExecuted() (gas: 0)
[PASS] testSplitter() (gas: 3473977)
[PASS] testSystemTokens() (gas: 3959026)
[PASS] testUseEta() (gas: 343170)
[SKIP] testVestDAI() (gas: 0)
[SKIP] testVestMKR() (gas: 0)
[SKIP] testVestSKY() (gas: 0)
[SKIP] testYankDAI() (gas: 0)
[SKIP] testYankMKR() (gas: 0)
[PASS] testsWhitelistSparkProxyOnLitePsm() (gas: 2872518)
Suite result: ok. 18 passed; 0 failed; 24 skipped; finished in 369.65s (934.08s CPU time)

Ran 2 test suites in 370.23s (414.11s CPU time): 20 tests passed, 0 failed, 24 skipped (44 total tests)

@0xp3th1um
Copy link
Collaborator

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
  • 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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
  • 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

@0xdecr1pto 0xdecr1pto merged commit a928088 into master Nov 1, 2024
3 checks passed
@amusingaxl amusingaxl deleted the 2024-10-31 branch November 4, 2024 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants