---
# System prepended metadata

title: Open Dollar Production Deployment Parameters

---

# 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



