Deployment

This page documents the steps for actually deploying the multicollateral upgrade to production.

⚠️ Warning

Make sure you really understand the deployment process before applying it to production, especially for the contracts part.

💡 Tips

The patch for Linear-finance/linear-dev-cli demonstrates how each of the additional collateral token is handled. It could be a useful source of reference.

💡 Tips

It might be helpful to practice/test by deploying a development environment with a version or Linear-finance/linear-dev prior to the upgrade, and then upgrading it.

Assumed collateral configuration

NameSymbolDecimals
Linear TokenLINA18
Wrapped BNBWBNB18
BTCB TokenBTCB18
Ethereum TokenETH18

ℹ️ Note

Code changes to services and web apps are required if you plan to deploy different collateral tokens.

Deploying contract changes

ℹ️ Note

This section only documents the deployment steps. See the contract changes page for details.

Deploying new SafeDecimalMath instance

Due to changes in SafeDecimalMath, a new instance of the library needs to be deployed. Once deployed, the address of this new instance should be used in any subsequent step where any contract using the libarary is upgraded/deployed.

Deploying the DebtDistribution contracts

Apart from turning some contracts from singleton deployments into being collateral-specific, the upgrade also adds a new contract DebtDistribution. This contract needs to be deployed first, as the collatera-specific contracts rely on it to function.

Once deployed, take note of its address as it will be needed for the subsequent steps.

Deciding on Collateral ID

For each collateral token (including LINA), you must decide on a Collateral ID to use. This Collateral ID could be different from the token symbol itself, but it's recommended to simply use the symbol. The Collateral ID will be needed when activating the tokens.

An example of deriving the Collateral ID from the string value "LINA" using ethers.js's formatBytes32String function:

const collateralId = formatBytes32String("LINA");

Upgrading LINA contracts

This step involves upgrading existing collateral-specific contracts for LINA to make them multi-collateral-aware.

Specifically, the following contracts need to be upgraded:

  • LnBuildBurnSystem
  • LnCollateralSystem
  • LnDebtSystem
  • LnLiquidation

Once upgraded, activate LINA as collateral by sending these two transactions:

  1. Calling addCollateral() on DebtDistribution with LINA's LnDebtSystem address and its Collateral ID to register the token.
  2. Calling setDebtDistribution() on LINA's LnDebtSystem contract with DebtDistribution's address to link the two contracts.

ℹ️ Note

With the multi-collateral system, each token must be activated to become usable as collateral. This includes LINA. So it's important for the activation step to be performed in a timely manner to limit downtime.

ℹ️ Note

Once this step is done, the system would have techinically already enabled multi-collateral support. It's just that LINA is the only activated collateral token.

It's therefore a good opportunity to pause here and test that everything still works as expected before proceeding.

Deploying new collateral contracts

ℹ️ Note

Some contract constructor fields require addresses of contracts that are not yet deployed. While it's technically possible to pre-compute those addresses before deployment, it might be easier to simply feed the constructor with mock addresses first (e.g. 0x0000000000000000000000000000000000000001) and configure them later via setters once all other contracts are deployed.

For each collateral token:

  1. Deploy LnDebtSystem.
  2. Deploy LnBuildBurnSystem, leaving the _collaterSys and _liquidation arguments as mocked addresses.
  3. Deploy LnCollateralSystem, leaving the _mRewardLocker and _liquidation arguments as mocked addresses.
  4. Deploy LnLiquidation, leaving the _lnRewardLocker argument as mocked address.

⚠️ Warning

The address for LnRewardLocker is deliberately left out (and not filled back in later) for LnCollateralSystem and LnLiquidation, as only the native collateral token (i.e. LINA) can be locked as rewards. Incorrectly feeding LINA's LnRewardLocker address to these contracts will result in system misbehaviors.

  1. Deploy LnRewardSystem, using LINA's LnRewardLocker's address for the _rewardLockerAddress argument.

  2. Configure the collateral token by setting the following values on LnConfig:

    • COLLATERALID_BuildRatio
    • COLLATERALID_LiqRatio
    • COLLATERALID_LiqMarkerReward
    • COLLATERALID_LiqLiquidatorReward
    • COLLATERALID_LiqDelay

    where COLLATERALID must be replaced with the actual Collateral ID chosen. For example, if the chosen Collateral ID is BTCB, then the first key would be BTCB_BuildRatio.

  3. Assign the following roles on LnAccessControl:

    • ISSUE_ASSET for LnBuildBurnSystem
    • BURN_ASSET for LnBuildBurnSystem
    • LnDebtSystem for LnBuildBurnSystem
    • LOCK_REWARD for LnRewardSystem
  4. Fill some of the addresses left out during deployment:

    • Call setCollateralSystemAddress() on LnBuildBurnSystem
    • Call setLiquidationAddress() on LnBuildBurnSystem
    • Call setLiquidationAddress() on LnCollateralSystem
  5. Call updateTokenInfo() on LnCollateralSystem with the token's Collateral ID and address.

  6. Set up LnOracleRouter to handle price queries for the Collateral ID, if the Collateral ID doesn't already map to a valid oracle setting.

Activating new collateral tokens

⚠️ Warning

Once this step is done, users can already start using the new collateral tokens (even if the web apps haven't been updated). Old subgraphs are not aware of the upgrade and would serve inaccurate data if anyone actually uses the new tokens.

To avoid this, consider deploying and synchronizing the new subgraphs first before proceeding with this step. This is especially true considering that some subgraphs take a long time to synchronize.

For each collateral token, follow the same steps taken to activate LINA:

  1. Calling addCollateral() on DebtDistribution with the collateral token's LnDebtSystem address and its Collateral ID to register the token.
  2. Calling setDebtDistribution() on the collateral token's LnDebtSystem contract with DebtDistribution's address to link the two contracts.

Upgrading subgraphs

See this subgraphs section for the list of changed subgraphs.

To deploy new subgraphs, first make changes to Linear-finance/graph-registry to bump subgraph versions and update environment variables.

Then, deploy the updated subgraphs and wait for the synchronization to finish. After that, update Linear-finance/graph-proxy-config to start routing traffic to the new subgraphs.

💡 Tips

See the patch in Linear-finance/linear-dev for subgraph deployment changes.

Upgrading services

See the workers section and Docker services section for the list of changed services.

💡 Tips

See the patch in Linear-finance/linear-dev for service deployment changes.

Upgrading web apps

The final step is upgrading the web apps to enable end users to interact with the new collateral tokens. See this page for a list of changed web apps.