Open Term Loan Deployment

Phase 1 - Deploy New Contracts

Deploy and verify the following contracts using a single forge script:

New PoolDeployer

  1. New PoolDeployer pointing to existing mapleGlobalsProxy

Globals and PoolManager Upgrade Contracts

  1. Globals v2.0.0 implementation

  2. PoolManager v2.0.0 implementation

Fixed Term Loan Upgrade Contracts

  1. MapleLoan v5.0.1 implementation

  2. MapleLoanInitializer for v5.0.0 deployments

  3. MapleLoanMigrator for v4.0.0 -> v5.0.0 upgrades

  4. LoanManager v3.0.1 implementation

Open Term Loan Manager Contracts

  1. LoanManagerFactory

  2. LoanManagerImplementation v1.0.0 implementation

  3. LoanManagerInitializer for v1.0.0 deployments

Open Term Loan Contracts

  1. MapleLoanFactory

  2. MapleLoanInitializer for v1.0.1 deployments

  3. MapleLoanImplementation v1.0.1 implementation

  4. MapleRefinancer for v1.0.1 deployments

Phase 2 - Configuration of Protocol by Governor

This phase will be set up by the smart contracts team with JSONs and Gnosis Safe. This set of transactions will be simulated on Tenderly and validated. This will include three main actions:

  1. Upgrade Globals

  2. Allowlist all relevant contracts in Globals

  3. Configure factories with newest contract versions

  4. Upgrade all PoolManager and LoanManager contracts

  5. Set canDeploy for all existing borrowers

Details are outlined below.

Upgrade Globals

globals.setImplementation(newGlobalsImplementation)

Allowlist All Contracts

globals_.setValidInstanceOf("LIQUIDATOR_FACTORY",         liquidatorFactory,        true);
globals_.setValidInstanceOf("POOL_MANAGER_FACTORY",       poolManagerFactory,       true);
globals_.setValidInstanceOf("WITHDRAWAL_MANAGER_FACTORY", withdrawalManagerFactory, true);

globals_.setValidInstanceOf("FT_LOAN_FACTORY", fixedTermLoanFactory, true);
globals_.setValidInstanceOf("LOAN_FACTORY",    fixedTermLoanFactory, true);

globals_.setValidInstanceOf("OT_LOAN_FACTORY", openTermLoanFactory, true);
globals_.setValidInstanceOf("LOAN_FACTORY",    openTermLoanFactory, true);

globals_.setValidInstanceOf("FT_LOAN_MANAGER_FACTORY", fixedTermLoanManagerFactory, true);
globals_.setValidInstanceOf("LOAN_MANAGER_FACTORY",    fixedTermLoanManagerFactory, true);

globals_.setValidInstanceOf("OT_LOAN_MANAGER_FACTORY", openTermLoanManagerFactory, true);
globals_.setValidInstanceOf("LOAN_MANAGER_FACTORY",    openTermLoanManagerFactory, true);

globals_.setValidInstanceOf("FT_REFINANCER", fixedTermRefinancerV2, true);
globals_.setValidInstanceOf("REFINANCER",    fixedTermRefinancerV2, true);

globals_.setValidInstanceOf("OT_REFINANCER", openTermRefinancerV1, true);
globals_.setValidInstanceOf("REFINANCER",    openTermRefinancerV1, true);

globals_.setValidInstanceOf("FEE_MANAGER", fixedTermFeeManagerV1, true);

globals_.setCanDeployFrom(poolManagerFactory,       poolDeployerV2, true);
globals_.setCanDeployFrom(withdrawalManagerFactory, poolDeployerV2, true);

// setCanDeploy for all valid borrowers for OTL Factory
for (uint256 i; i < validBorrowers.length; ++i) {
    globals_.setCanDeployFrom(openTermLoanFactory, validBorrowers[i], true);
}

Configure Factories

Register PoolManager Version v2.0.0 and v1.0.0 -> v2.0.0 Upgrade

poolManagerFactory.registerImplementation(200, poolManagerImplementationV200, poolManagerInitializer);
poolManagerFactory.setDefaultVersion(200);
poolManagerFactory.enableUpgradePath(100, 200, address(0));

Register FixedTermLoan Version v5.0.1 and v4.0.0 -> v5.0.1 Upgrade

fixedTermLoanFactory.registerImplementation(501, fixedTermLoanImplementationV501, fixedTermLoanInitializerV500);
fixedTermLoanFactory.setDefaultVersion(501);
fixedTermLoanFactory.enableUpgradePath(400, 501, fixedTermLoanMigratorV500);

Register FixedTermLoanManager Version v3.0.1 and v2.0.0 -> v3.0.1 Upgrade

fixedTermLoanManagerFactory.registerImplementation(301, fixedTermLoanManagerImplementationV301, fixedTermLoanManagerInitializerV300);
fixedTermLoanManagerFactory.setDefaultVersion(301);
fixedTermLoanManagerFactory.enableUpgradePath(200, 301, address(0));

Register OpenTermLoan Version v1.0.1

openTermLoanFactory.registerImplementation(101, openTermLoanImplementationV101, openTermLoanInitializerV100);
openTermLoanFactory.setDefaultVersion(101);

Register OpenTermLoanManager Version v1.0.0

openTermLoanManagerFactory.registerImplementation(100, openTermLoanManagerImplementationV100, openTermLoanManagerInitializerV100);
openTermLoanManagerFactory.setDefaultVersion(100);

Upgrade all PoolManagers

Upgrade all (currently 8) outstanding PoolManager contracts.

poolManager.upgrade(200, "0x");

Upgrade all Fixed Term LoanManagers

Upgrade all (currently 8) outstanding LoanManager contracts.

loanManager.upgrade(301, "0x");

This procedure contains a significant amount of function calls, so it will need to determined if it can all be performed in one transaction or will require multiple.

Phase 3 - Security Admin Upgrades all Loans

This step will also be done with a JSON fed into a Gnosis Safe multisig, which will be simulated against Tenderly and validated by the smart contracts team before being performed on mainnet. The number of function calls will depend on the number of outstanding loans at deployment.

loan.upgrade(501, "0x")

Key Deprecation in Globals

Once the smart contracts team has deemed it safe, all old keys used for allowlisting can be set to false.

Remove Contracts from Old Allowlist

globals_.setValidInstanceOf("LIQUIDATOR",         liquidatorFactory,           false);
globals_.setValidInstanceOf("LOAN_MANAGER",       fixedTermLoanManagerFactory, false);
globals_.setValidInstanceOf("POOL_MANAGER",       poolManagerFactory,          false);
globals_.setValidInstanceOf("WITHDRAWAL_MANAGER", withdrawalManagerFactory,    false);
globals_.setValidInstanceOf("LOAN",               fixedTermLoanFactory,        false);

globals_.setValidPoolDeployer(poolDeployer, false);

Post-Upgrade

Adding Open Term Loan Managers

After the protocol has been deployed, the PoolDelegates can call:

poolManager.addLoanManager(openTermLoanManagerFactory)

to add a new OpenTermLoanManager to their Pools if they would like to fund new Open Term Loans.

Last updated