Skip to content

Latest commit

 

History

History
191 lines (185 loc) · 13.2 KB

rwa-checklists.md

File metadata and controls

191 lines (185 loc) · 13.2 KB

RWA Checklists

RWA Onboarding Checklist

  • Deployed Contracts
    • RwaToken (Token Used as Collateral In Adapter)
      • deployed via RwaTokenFactory
        • Fab matches chainlog
        • ensure source matches GitHub code and it's consistent with previous RWA onboarding
        • Rwa Token transferred to MCD Pause Proxy
        • createRwaToken parameters are correct
        • name is in RWA-XYZ format
        • symbol is in RWAXYZ format
        • recipient matches MCD Pause Proxy
    • AuthGemJoin (Join Adapter)
      • deployed via JoinFab
        • Fab matches chainlog
        • ensure source matches GitHub code and it's consistent with previous RWA onboarding (NOTE: Etherscan may have a bug where it displays additional code for AuthGemJoin. In this case, using cast interface or otherwise, ensure that this code cannot be executed)
        • newAuthGemJoin parameters are correct
          • owner matches PAUSE_PROXY
          • ilk is the bytes32 representation of "RWAXYZ-A"
            • cast --to-ascii <bytes32> matches ASCII Ilk
            • cast --to-bytes32 $(cast --from-ascii "RWAXYZ-A") matches bytes32 (to check the amount of padding zeroes is correct)
          • gem matches RwaToken deployed contract
        • check wards
          • MCD_PAUSE_PROXY is relied
          • deployer is denied
        • no other address has been relied
    • RwaUrn/RwaUrn2
      • contract is verified on etherscan
        • ensure 0.6.12 solc version is used
        • ensure optimizations are off
        • ensure license is specified (SPDX in code or otherwise)
        • ensure source matches GitHub code and it's consistent with previous RWA onboardings
      • constructor args are correct and match Chainlog
        • vat matches MCD_VAT
        • jug matches MCD_JUG
        • gemJoin matches MCD_JOIN_RWAXYZ_A (Per spell code)
        • daiJoin matches MCD_JOIN_DAI
        • outputConduit matches RwaOutputConduit<2,3> (Per spell code)
      • check wards
        • MCD_PAUSE_PROXY is relied
        • deployer is denied
        • no other address has been relied
    • RwaJar
      • contract is verified on etherscan
        • ensure 0.6.12 solc version is used
        • ensure optimizations are off
        • ensure license is specified (SPDX in code or otherwise)
        • ensure source matches GitHub code and it's consistent with previous RWA onboarding
      • constructor arg matches ChainLog
        • chainlog
      • no wards
    • RwaInputConduit<2>/RwaSwapInputConduit<2>
      • contract is verified on etherscan
        • ensure 0.6.12 solc version is used
        • ensure optimizations are off
        • ensure license is specified (SPDX in code or otherwise)
        • ensure source matches GitHub code and it's consistent with previous RWA onboarding
      • constructor args are correct and match chainlog
        • dai
        • to (RwaUrn, RwaJar)
        • gov (v1)
        • psm, gem (v3)
      • check wards
        • MCD_PAUSE_PROXY is relied
        • deployer is denied
        • no other address has been relied
    • RwaOutputConduit<2>/RwaSwapOutputConduit
      • contract is verified on etherscan
        • ensure 0.6.12 solc version is used
        • ensure optimizations are off
        • ensure license is specified (SPDX in code or otherwise)
        • ensure source matches GitHub code and it's consistent with previous RWA onboarding
      • constructor args are correct and match chainlog
        • dai
        • gov (v1)
        • psm, gem (v3)
      • check wards
        • MCD_PAUSE_PROXY is relied
        • deployer is denied
        • no other address has been relied
    • Risk Parameters Match Doc
      • duty(stability fee)
      • line(debt ceiling)
      • mat (liquidation ratio)
      • val (oracle price)
        • val is computed as "debt_ceiling * [ (1 + rwa_stability_fee ) ^ (minimum_deal_duration_in_years) ] * liquidation_ratio"
        • val matches locally executable formula (e.g. // bc -l <<< 'scale=18; 50000000 * e(l(1.07) * (3342/365)) * 1.00' | cast --to-wei)
      • tau (pre-agreed remediation period)
      • doc (IPFS Hash)
    • Onboarding Actions
      • ilk matches the format RWAXYZ-A
      • Sanity Checks (constructor args, public vars, ... via require condition)
      • MIP21_LIQUIDATION_ORACLE.init
      • vat.init.ilk
      • jug.init.ilk (this will set duty to RAY (zero pct) by default)
      • vat rely join
      • Increase Ilk Debt Ceiling (set DC + increase Global DC)
      • File Ilk pip in the spotter
      • File Ilk mat in the spotter
      • Poke spotter to pull in the price
      • join rely urn
      • Access Control
        • hope (operator, pause proxy)
        • mate (operator, pause proxy as fallback if required)
        • kiss (whitelist for urn destination address who)
    • Fileable (RwaSwapOutputConduit and RwaSwapInputConduit)
      • quitTo (file the appropriate address for conduits per technical assessment)
    • New Chainlog Entries
      • RWAXYZ
      • PIP_RWAXYZ precomputed via cast compute-address $MIP21_LIQUIDATION_ORACLE
        • Note that a nonce change for MIP21_LIQUIDATION_ORACLE prior to casting will cause this to be incorrect
      • MCD_JOIN_RWAXYZ_A
      • RWAXYZ_A_URN
      • RWAXYZ_A_JAR
      • RWAXYZ_A_INPUT_CONDUIT
      • RWAXYZ_A_OUTPUT_CONDUIT
    • Chainlog Bump
      • Patch x.x.1
    • Add Ilk to IlkRegistry
      • put is used
      • class is 3
      • name matches forum post (e.g. "RWA007-A: Monetalis Clydesdale")
    • Ensure DssExecLib is used for the Onboarding (e.g. DssExecLib.vat)
    • Test Coverage (Follow Previous Test Patterns)
      • testNewChainlogValues
      • testNewIlkRegistryValues
      • testRWAXYZ_INTEGRATION_CONDUITS_SETUP
      • testRWAXYZ_INTEGRATION_BUMP
      • testRWAXYZ_INTEGRATION_TELL
      • testRWAXYZ_INTEGRATION_TELL_CURE_GOOD
      • testFailRWAXYZ_INTEGRATION_CURE_BEFORE_TELL
      • testRWAXYZ_INTEGRATION_TELL_CULL
      • testRWAXYZ_PAUSE_PROXY_OWNS_RWAXYZ_TOKEN_BEFORE_SPELL
      • testRWAXYZ_SPELL_LOCK_OPERATOR_DRAW_WIPE_FREE
      • testFailRWAXYZ_DRAW_ABOVE_LINE
      • testFailRWAXYZ_OUTPUT_CONDUIT_PUSH_ABOVE_BALANCE
      • testRWAXYZ_OPERATOR_LOCK_DRAW_CAGE
      • testRWAXYZ_SPELL_LOCK
      • addresses_<mainnet, goerli>.sol
      • config.sol

RWA Update Checklist

  • 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_RWAXYZ 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 (vat.ilks(ilk).line) is 0 (OR is being set to 0 in the current spell)
      • RwaLiquidationOracle.tell(ilk) call is present
      • IF RWAXYZ_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)

RWA Offboarding Checklist

  • The debt ceiling (vat.ilks(ilk).line) is 0 OR is currently being set to 0.
  • IF soft liquidation .tell(ilk) has NOT been called for the ilk in a previous spell:
    • RwaLiquidationOracle.tell(ilk) call is present
    • IF RWAXYZ_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 there is debt in the RWA Vault (vat.urns(ilk, RWAXYZ_A_URN).art > 0), proceed with the write-off (i.e.: vault is in default):
    • Obtain toc and tau from RwaLiquidationOracle.ilks(ilk)
    • IF block.timestamp >= toc + tau, then
      • IF the stability fee for the ilk is not zero (jug.ilks(ilk).duty > 1 * RAY), jug.drip(ilk) call is present
      • RwaLiquidationOracle.cull(ilk, RWAXYZ_A_URN) call is present
      • IF RWAXYZ_A_INPUT_CONDUIT is an instance of TinlakeMgr (it is a Centrifuge integration), additional TinlakeMgr.cull() call is present
    • OTHERWISE the write-off can only happen in a future spell