# Open Dollar Production Deployment Parameters ### Relevant files: - Testnet Params: https://github.com/open-dollar/od-contracts/blob/dev/script/GoerliParams.s.sol - Mainnet Params: https://github.com/open-dollar/od-contracts/blob/dev/script/MainnetParams.s.sol - Params: https://github.com/open-dollar/od-contracts/blob/dev/script/Params.s.sol - Common: https://github.com/open-dollar/od-contracts/blob/dev/script/Common.s.sol # Governance ### timelockController - https://docs.openzeppelin.com/contracts/4.x/api/governance#TimelockController - https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/governance/TimelockController.sol Enforces the delay period for all maintenance proposals ```js minDelay: 1 day proposers: [governor, admin] // members executors: [governor, admin] // members admin: [governor, admin] // Can modify proposers/executors ``` ### ODGovernor No Bravo extension. No ability to update the configuration. - Voting: - Yes (counts towards quorum) - No (does not count towards quorum) ## ODGovernor Durations are calculated using blocks, at 12 seconds per block ```js initialVotingDelay: 3600 // 12 hours to buy more votes initialVotingPeriod: 14400 // 2 days after the initial initialVotingDelay initialProposalThreshold: 5000*(10**18) // Min needed to create a proposal. 0.1% @ 10M totalSupply = 10,000 ODG // percentage-to-pass-quorum // 1% of supply ~= 100,000 ODG // 0.3% is 30,000 ODG GovernorVotesQuorumFraction: 2 // 20k ODG ``` ## TimelockController ```js // Timelock queue length (after a proposal passes, before execution) minDelay: 1 days; ``` # Protocol ## Vault721 ```js blockDelay: 3 timeDelay: 1 hour ``` ## SAFEEngine ```js safeDebtCeiling: 3_000_000 * WAD, // WAD The max amount of debt that can be generated by a SAFE globalDebtCeiling: 10_000_000 * RAD // RAD The max amount of debt that can be generated by the system ``` ## accountingEngineParams ```js surplusIsTransferred: 0 // Depends on outcome of issue #39 Boolean if surplus that is transfered to external address. NOTE: check out tax collector here. surplusDelay: 1 days // Limits the frequency of the surplus auction popDebtDelay: 1 days // Limits the frequency of debt auction disableCooldown: 3 days // Backup in case GlobalSettlement.processSAFE has a bug, preventing surplus being locked in AccountingEngine surplusAmount: 100e45, // 100 COINs surplusBuffer: 1000e45, // 1000 COINs Surplus auctions cannot be started unless surplus i > _debtBalance + surplusAmount + surplusBuffer debtAuctionMintedTokens: 1000 * WAD, // 1000 PROTOCOL TOKEN debtAuctionBidSize: 100e45 // 100 COINs ``` ## debtAuctionHouseParams ```js bidDecrease: 1.05e18, // -5 % amountSoldIncrease: 1.5e18, // +50 % bidDuration: 3 hours, totalAuctionLength: 2 days ``` ## surplusAuctionHouseParams ```js bidIncrease: 1.01e18, // +1 % bidDuration: 6 hours, totalAuctionLength: 1 days, // restartAuction bidReceiver: governor, recyclingPercentage: 0.5e18 // 50% is burned ``` ## liquidationEngineParams ```js onAuctionSystemCoinLimit: 100_000 * RAD // 100_000 COINs saviourGasLimit: 10_000_000 // 10M gas ``` ```js if ( currentOnAuctionSystemCoins >= _params.onAuctionSystemCoinLimit || _params.onAuctionSystemCoinLimit - currentOnAuctionSystemCoins < _debtFloor ) revert LiqEng_LiquidationLimitHit(); ``` ## stabilityFeeTreasuryParams ```json // Maximum amount of internal coins that the treasury can hold treasuryCapacity: 1_000_000e45, // 1M COINs // Minimum amount of internal coins that the treasury must hold in order to allow pulling funds pullFundsMinThreshold: 0, // no threshold // Minimum amount of time that must pass between surplus transfers surplusTransferDelay: 1 days ``` ## taxCollectorParams ```json // Address of the primary tax receiver primaryTaxReceiver: accountingEngine, // Global stability fee [ray] globalStabilityFee: RAY, // no global SF // Max stability fee range of variation maxStabilityFeeRange: RAY - MINUS_0_5_PERCENT_PER_HOUR, // +- 0.5% per hour // Max number of secondary tax receivers maxSecondaryReceivers: 1 ``` ## taxCollectorSecondaryTaxReceiver ```js receiver: address(stabilityFeeTreasury), canTakeBackTax: true, // [bool] taxPercentage: 0.5e18 // [wad%] ``` # PID ## oracleRelayerParams ```js redemptionRateUpperBound: RAY * WAD, // RAY redemptionRateLowerBound: 1 // RAY ``` ## pidControllerParams ```js perSecondCumulativeLeak: // 999_999_711_200_000_000_000_000_000HALF_LIFE_30_DAYS Decay constant for the integral deviation noiseBarrier: 0.995e18, // 0.5% feedbackOutputLowerBound: -int256(RAY - 1), // (unbounded) Minimum limit for the redemption rate. feedbackOutputUpperBound: RAD, // (unbounded) Maximum limit for the redemption rate integralPeriodSize: 1 hours // Minimum duration required to calculate integral deviation ``` ## pidControllerGains ```js kp: int256(111_001_102_931), // imported from RAI ki: int256(32_884) // imported from RAI ``` ## pidRateSetterParams ```js updateRateDelay: 1 hours // Time gap between successive redemption rate adjustments ``` # Global Settlement ## globalSettlementParams ```js shutdownCooldown: 3 days ``` ## postSettlementSAHParams ```js bidIncrease: 1.01e18, // +1 % bidDuration: 3 hours, totalAuctionLength: 1 days ``` # Collateral Unit conversion reference guide ```js WAD 1e18 1000000000000000000 RAY 1e27 1000000000000000000000000000 RAD 1e45 1000000000000000000000000000000000000000000000 uint256 constant PLUS_1_5_PERCENT_PER_YEAR = 1_000_000_000_472_114_805_215_157_978; uint256 constant PLUS_1_75_PERCENT_PER_YEAR = 1_000_000_000_550_051_944_812_439_051; uint256 constant PLUS_1_85_PERCENT_PER_YEAR = 1_000_000_000_581_197_104_947_698_371; uint256 constant PLUS_2_PERCENT_PER_YEAR = 1_000_000_000_627_937_192_491_029_810; uint256 constant PLUS_5_PERCENT_PER_YEAR = 1_000_000_001_547_125_957_863_212_448; ``` ### WSTETH ```json // OracleRelayerCollateralParams safetyCRatio: 1.25e27, liquidationCRatio: 1.20e27 // 120% // TaxCollectorCollateralParams // 3.154×10^7 seconds in 1 year // NOTE: 5%/yr => 1.05^(1 / 3.154×10^7) = 1 + 1.54713e-9 stabilityFee: PLUS_1_85_PERCENT_PER_YEAR; // +1.85%/yr // SAFEEngineCollateralParams debtCeiling: 10_000_000 * RAD, // 10M COINs for all WSTETH safes debtFloor: 200 * RAD; // 200 COIN // LiquidationEngineCollateralParams liquidationPenalty: 1.05e18; // (5%) WAD Penalty applied to the debt of the SAFE that is being liquidated. This penalty represents an excess in the amount of debt that the collateral auction needs to cover. liquidationQuantity: 100_000e45 // RAD Max amount of debt that can be liquidated in each liquidation // CollateralAuctionHouseParams minimumBid: 100e18, // 100 COINs minDiscount: 1e18, // no discount. starting discount maxDiscount: 0.9e18, // 10% the maximum discount that can be applied // Calculation: 0.99998575212^3600 = 0.950000532931460689867615 perSecondDiscountUpdateRate: 0.99998575212e27 // RAY Determines the rate at which the discount increases for each second the auction is live ``` ### RETH ```json // OracleRelayerCollateralParams safetyCRatio: 1.25e27, liquidationCRatio: 1.20e27 // TaxCollectorCollateralParams stabilityFee: PLUS_1_75_PERCENT_PER_YEAR; // +1.75%/yr // SAFEEngineCollateralParams debtCeiling: 10_000_000 * RAD, debtFloor: 200 * RAD; // LiquidationEngineCollateralParams liquidationPenalty: 1.05e18; // 5% liquidationQuantity: 100_000e45 // 100,000 COINs // CollateralAuctionHouseParams minimumBid: 100e18, // 100 COINs minDiscount: 1e18, maxDiscount: 0.9e18, perSecondDiscountUpdateRate: 0.99998575212e27 ``` ### ARB ```json // OracleRelayerCollateralParams safetyCRatio: 1.85e27 liquidationCRatio: 1.75e27 // TaxCollectorCollateralParams stabilityFee: PLUS_5_PERCENT_PER_YEAR; // +5%/yr // SAFEEngineCollateralParams debtCeiling: 5_000_000 * RAD, // 5M COINs debtFloor: 200 * RAD; // 200 COIN // LiquidationEngineCollateralParams liquidationPenalty: 1.1e18; // 10% liquidationQuantity: 100_000e45 // 100,000 COINs // CollateralAuctionHouseParams minimumBid: 100e18, // 100 COINs minDiscount: 1e18, maxDiscount: 0.9e18, perSecondDiscountUpdateRate: 0.99998575212e27 ``` # Oracles ## Oracle Parameters ### OD OD is not collateral, but an OD oracle is used to get the current market price 1. CamelotRelayer OD / ETH ```js address _baseToken: address _quoteToken: uint32 _quotePeriod: ``` 2. ChainlinkRelayer ETH / USD 4. DenominatedOracle (OD / ETH) * (ETH / USD) Chainlink ### ETH ETH is not collateral, but an ETH oracle is needed to calculate the price in USD for the other collateral tokens Decimals: 18 Oracles: 1. ChainlinkRelayer ETH / USD ```js address _aggregator: CHAINLINK_ETH_USD_FEED uint256 _staleThreshold: ``` DelayedOracle is not necessary, since the Rate Setter PID controller already includes a delay. ### ARB Decimals: Oracles: 1. ChainlinkRelayer ARB / USD ```js //MAINNET_CHAINLINK_ARB_USD_FEED address _aggregator: 0xb2A824043730FE05F3DA2efaFa1CBbe83fa548D6 uint256 _staleThreshold: = ; ``` 2. DelayedOracle ARB / USD ```js IBaseOracle _priceSource: _arbUSDPriceFeed uint256 _updateDelay: ORACLE_INTERVAL_PROD ``` ### WSTETH Rebasing: Decimals: Oracles: 1. ChainlinkRelayer WSTETH / ETH ```js address _aggregator: CHAINLINK_WSTETH_ETH_FEED uint256 _staleThreshold: ``` 2. DenominatedOracle (WSTETH / ETH) * (ETH / USD) ```js IBaseOracle _priceSource: _wstethETHPriceFeed IBaseOracle _denominationPriceSource: _ethUSDPriceFeed bool _inverted: false ``` 3. DelayedOracle WSTETH / USD ```js IBaseOracle _priceSource: _wstethUSDPriceFeed uint256 _updateDelay: ORACLE_INTERVAL_PROD ``` ### RETH Rebasing: Decimals: Oracles: 1. ChainlinkRelayer RETH / ETH ```js address _aggregator: CHAINLINK_RETH_ETH_FEED uint256 _staleThreshold: ``` 2. DenominatedOracle (RETH / ETH) * (ETH / USD) ```js IBaseOracle _priceSource: _rethETHPriceFeed IBaseOracle _denominationPriceSource: _ethUSDPriceFeed bool _inverted: false ``` 3. DelayedOracle RETH / USD ```js IBaseOracle _priceSource: _rethUSDPriceFeed uint256 _updateDelay: ORACLE_INTERVAL_PROD ``` ## Oracle Types ### CamelotRelayer ```js address _baseToken address _quoteToken uint32 _quotePeriod ``` ### ChainlinkRelayer ```js // @param _aggregator The address of the Chainlink aggregator address _aggregator // @param _staleThreshold The threshold after which the price is considered stale uint256 _staleThreshold ``` Validation calculation: ```js return block.timestamp - _feedTimestamp <= staleThreshold; ``` ### DenominatedOracle ```js // @param _priceSource Address of the base price source that is used to calculate the price IBaseOracle _priceSource // @param _denominationPriceSource Address of the denomination price source that is used to calculate price IBaseOracle _denominationPriceSource // @param _inverted Flag that indicates whether the price source quote should be inverted or not bool _inverted ``` ### DelayedOracle ```js // @param _priceSource The address of the non-delayed price source IBaseOracle _priceSource // @param _updateDelay The delay in seconds that should elapse between updates uint256 _updateDelay ``` # Jobs ### Accounting Job Reward: 1 OD 1. workPopDebtFromQueue 2. workAuctionDebt 3. workAuctionSurplus 4. workTransferExtraSurplus ### Liquidation Job Reward: 1 OD 1. workLiquidation ### Oracle Job Reward: 1 OD 1. workUpdateCollateralPrice 2. workUpdateRate # Liquidity ## Pools Available - Camelot ## Protocol Parameters ### OD Type: Camelot - Initial OD/ETH supply & price? (issue: https://github.com/open-dollar/od-contracts/issues/152) - Initial ODG/ETH supply & price? ### WSTETH ### CBETH ### RETH ### ARB ### MAGIC # Notes ## 9/24 Joseph & Ameen 1.rebasing; peg float, Rai-> rebasing RAI -> non-rebasing token 2. redemption of stablecoin for collateral makes things like liquity more secure. can be acomplished with the nft vaults later for OD. 3. stablecoin price floats with Eth if theres too much rai/eth liquidity, which is not ideal if target is more stability of the coin 4. bluechip rating agency conditions 5. Consider rebasing instead of floating price mechanics ## 9/28 Initial Review ### Joseph ODGovernor: [Tally Suggested Params](https://docs.tally.xyz/user-guides/deploying-governor-daos/choose-governor-parameters#how-to-pick-the-quorum) - initialVotingDelay: 3 days - initialVotingPeriod: 7 days - initialProposalThreshold: 2% - initialVotingProposal. No votes shall not count towards quorum accountingEngineParams: 50 WAD ### Hunter TimelockController: - proposers: determine the purpose and whether these roles are needed - executors - admin - minDelay: Research what value needed for 3 days Gnosis Safe: - Potentially the admin on `timelockController`? - What permissions does it have in the OD Protocol? 1. Multiplier is calculated using quoteToken, but not baseToken. Does this always assume baseToken is ETH w/ 18 decimals? Should we hard-code the base token in the scripts to avoid fudging this in the future? ## 10/4 Meeting with HAI - Debt auction params: do they pay off debt fast enough - a few hours / a few days is good enough. Not too important. - How does debt floor effect ability to liquidate underwater safes - Low as possible, liq still profitable. Couple hundred OD - Also dont want spam liquidation $5-15 for all jobs - Why would we need to change extraSurplusReceiver - Needing multiple buckets for tax purposes - setPerHourAllowance for job contracts is not being set currently - Will be used, may be overkill from RAI - Purpose of treasuryCapacity? - tax / legal reasons - taxCollectorSecondaryTaxReceiver How is taxPercentage used. Is this 50%? 0.5e18 // [wad%] - 50% sent to surplus and 50% back into protocol - In MainnetParams.s.sol, the calculation for stabilityFee may be wrong: RAY + 1.54713e18 // RAY - Can ignore, since that file has not been updated by hai team - DelayedOracle risk of lowering delay time? - Based on cost/frequency of chainlink updates - Based on giving people enough time to exit/modify positions - Liquidation jobs: - Overpay in order to remove concerns that jobs go uncompleted - Governance - Also using - Maxed out delays, wish they could make it longer on RAI - Time for people to unwind their positions - Time team to vote against, rally the troops TODO for OD 1. Determine chainlink cost / frequency a. ~0.0097 LINK = $0.072 per request 3. Determine oracle delays - 1 day 5. Determine job prices - see jobs above. 1 OD for all 7. Determine debt floor for each collateral - Must be enough that if the vault should be liquidated its worth is for people to do so. Maybe 200 OD, but should be as low as possible 7. Any tax reasons we need an additional extraSurplusReceiver? (legal question) 8. Determine safety and liquidation ratios for each collateral TODO for Pat - consequences of updateRateDelay being set for a very short time - In Rai it is 1 day iirc, decided to lower it down because of low gas fees, and to add more measurements that will compensate any measurement error. Effects on lowering, you have a rate with higher latency, but a bit less precision (since you are exponentiating by a smaller number) - Why no discounts on CollateralAuctionHouseParams - Ask in Discord - Does paying back debt also require satisfying safety ratio? - YES! See SAFEEngine.sol L182 https://github.com/open-dollar/od-contracts/blob/f823ab18b97f87b27ec972878e3dce8fcdc558ab/src/contracts/SAFEEngine.sol#L181-L182 - taxCollectorSecondaryTaxReceiver verify 0.5e18 [wad%] is really 50% TODO for HAI - In stabilityFeeTreasury, is `pullFundsMinThreshold` being used? Remaining questions: - maxStabilityFeeRange should we increase beyond 0.5%/hr - PID settings - updateRateDelay being set for a very short time - product/integral values - updateRateDelay & oracle delays - per-collateral accumulated rate. How does this behave? New questions for 10/18 - Outcome of the audit - Purpose of defi-wonderland repo - safety and liquidation ratios for each collateral - how often jobs need to be called - Debt floor 200 OD for all collateral ## Meeting with hai 10/18 Audit findings: - Anyone can disable protection on a safe (safe saviors) - missing debt check. lets user start debt auction when there is not debt. Questions - Choosing collateral ratios that are competitive with the rest of the market. needs research - moving the stability fee lever, vs. the collateral/safety ratio. - Jerome Powell method: opening a hot safe type with low debt ceiling, high stability fee. - Opposite example: Maker ETH-B, more for institutional investors. 1.3x leverage with comfort - Debt floor: is L2 10x cheaper? base answer on RAI debt floor. What amount do users show up with? Profitability isn't as important in the short-term. - Controller: market really reacts at 7-10%. How much debt/weight loss is in the system. How quickly do we arrive to 7-10%. Existing params are the best start. - dynamic liquidation, liq penalties dependent on the individual vs the market. Eg **Audit Takeaways:** - No check on collateral type when opening a safe, so safes can be opened with non-joined collateral types - SafeManager.addSAFE is not access controlled, but SafeManager.removeSAFE is restricted to safeAllowed modifier, so non-owners can add safes they don't own to their UI, but never remove - SafeManager.safeAllowed modifier is attached to SafeManager.allowSAFE, meaning any approved address can approve other addresses - It's unclear what the purpose of SafeManager.handlerAllowed is and who/when SafeManager.allowHandler is called since SafeHandler doesn't have logic to execute it - SafeManager.quitSystem takes arbitrary address for dst, so collateral and debt can be sent to non-existent SafeHandler in SafeEngine - In ProxyActions contracts, `tranferFrom` calls are not checked for success - DSProxy is payable, but does not send msg.value in delegatecall, possibly locking funds **OpenDollar Specific:** - Unclear how data migration will happen in protocol updgrade when Vault721 is not upgraded - Protocol upgrade without updating Vault721 will break mint function bc tokenId will be set back to zero (safeId), which would dubplicate tokenIds - NFT can be transferred to an ODProxy, which would trigger Vault721 to create proxy for the proxy; consequences need to be further investigated - SafeManager.openSAFE takes arbitrary address as owner (which should be proxy) but other addresses could be entered, which will no be accounted for in the proxyRegistry, possibly breaking the mint function ## Meeting 10/25 Topics: - Audit results - StabilityFeeTreasury `_modifyParameters` - PID playbook / pausing redemption rate changes - Legal - [US Stablecoin Bill](https://www.gillibrand.senate.gov/news/press/release/lummis-gillibrand-introduce-landmark-legislation-to-create-regulatory-framework-for-digital-assets/) - Follow up on PID-master advisor - Peaceful Money Alliance / Resolution / Directive / call for contributors TODO for OD: - Decide which contracts have admin at launch (`_modifyParameters`) P 2x less sensitive, increase i rate. decay rate to 90 day half-life i rate creeping up leads to inevitable longer TWAP? ![](https://hackmd.io/_uploads/By459xPGa.png) How much volume should be pushed to close the gap ## Meeting 11/1 **Testnet Launch** - Tomorrow :dancer: **Governance** - Hai team members to be delegates - PID advisor Bert - Tally - Governance control (modify parameters) **Peaceful Money Alliance** - Identifying community allies: Dsentra Illiquid staking chat > Peaceful means that all contractual obligations are enforced entirely in the digital space by math and the fundamental principals of physics. This is in contrast to the current system which relies on violence in the physical world to enforce contracts and rules (jail time, intimidation, and death). > > We are building a future that is centered around financial tools that rely only exclusively peaceful mechanisms. These mechanisms are made possible by innovations in cryptography, the interconnectedness of all humans via the internet, and the intentional and radical choices we make, as individuals, to support systems in alignment with humanity's highest purpose. **Engineering** - Ajand **Code4rena audit** needing items additional review: - https://github.com/code-423n4/2023-10-opendollar-findings/issues/46 - https://github.com/code-423n4/2023-10-opendollar-findings/issues/380 and https://github.com/code-423n4/2023-10-opendollar-findings/issues/196 are related. convo with hai here: https://discord.com/channels/1110925389464883201/1116039862596931716/1138805078401237062 - mismatch safe debt https://github.com/code-423n4/2023-10-opendollar-findings/issues/371 **Insurance policy** ## Meeting 11/16 ## Meeting 11/29 New Strategy - Smaller basket of LST - Focus on Institutional investments - Yield, security, simplicity TVL goals: Launching a Moloch DAO / Enzyme Hai v1.0.0 Contract changes https://github.com/open-dollar/od-contracts/pull/262 Pitching to DAOs with Treasuries Prisma.finance messaging is a good example. Don't give example of Rebate module - kingfish One-click feature for strategy A,B,C. Leveraging. Partnerships for farming. Bridge feature Abstract flash-loan Redeeming against vault Borrow collateral from a vault Incentives- looked at what was available on optimism, Ask Kingfish for what incentives to allocate to each pool Blast doesnt have a product, used multi-sig for managing pre-protocol incentivees ## Meeting 1/31/24 Voluntary exchange vs ethical exchange ✅ Separation of Church and State ⬜️ Separation of Money and State (coming soon