From 149adec79ae35fedcf53590e7f3a3eda4a02896e Mon Sep 17 00:00:00 2001 From: kasperpawlowski Date: Mon, 10 Aug 2026 13:48:50 +0200 Subject: [PATCH] refactor: deploy self-collateralized markets without the EdgeFactory The EdgeFactory is deprecated: its address is removed from the euler-interfaces address book and the edgeFactory field is dropped from the PeripheryAddresses struct in evk-periphery, so the script would read address(0) today and stop compiling on the next submodule bump. Instead of depending on the on-chain factory, replicate its deployment flow directly: deploy the router via the (kept) oracle router factory, reuse or create the escrowed collateral singleton vault via the (kept) escrowed collateral perspective, deploy the borrowable vault, configure LTV and renounce governance - identical parameters and ordering to EdgeFactory.deploy for the two-vault case. --- .../SelfCollateralizationBase.s.sol | 66 +++++++++++++------ 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/script/self-collateralization/SelfCollateralizationBase.s.sol b/script/self-collateralization/SelfCollateralizationBase.s.sol index 0821e19..706f7ca 100644 --- a/script/self-collateralization/SelfCollateralizationBase.s.sol +++ b/script/self-collateralization/SelfCollateralizationBase.s.sol @@ -3,38 +3,64 @@ pragma solidity ^0.8.0; import {BatchBuilder} from "evk-periphery-scripts/utils/ScriptUtils.s.sol"; -import {IEdgeFactory} from "evk-periphery/EdgeFactory/interfaces/IEdgeFactory.sol"; +import {GenericFactory} from "evk/GenericFactory/GenericFactory.sol"; +import {IEVault} from "evk/EVault/IEVault.sol"; +import {EulerRouter} from "euler-price-oracle/EulerRouter.sol"; +import {IEulerRouterFactory} from "evk-periphery/EulerRouterFactory/interfaces/IEulerRouterFactory.sol"; +import {EscrowedCollateralPerspective} from "evk-periphery/Perspectives/deployed/EscrowedCollateralPerspective.sol"; +/// @dev Deploys a two-vault self-collateralized market: an escrowed collateral vault and a +/// borrowable vault on the same asset, priced 1:1 through a governance-renounced router. +/// Replicates the deployment flow of the deprecated EdgeFactory without relying on it. abstract contract SelfCollateralizationBase is BatchBuilder { uint16 internal constant BLTV = 0.94e4; uint16 internal constant LLTV = 0.95e4; + uint16 internal constant LIQ_COOL_OFF_TIME = 1; + uint16 internal constant MAX_LIQ_DISCOUNT = 0.15e4; function execute(address token, address irm) public returns (address, address[] memory) { - IEdgeFactory.DeployParams memory params; + startBroadcast(); - params.vaults = new IEdgeFactory.VaultParams[](2); - params.vaults[0] = IEdgeFactory.VaultParams({asset: token, irm: address(0), escrow: true}); - params.vaults[1] = IEdgeFactory.VaultParams({asset: token, irm: irm, escrow: false}); + // Deploy the oracle router, governed by the deployer until configured + EulerRouter router = + EulerRouter(IEulerRouterFactory(peripheryAddresses.oracleRouterFactory).deploy(getDeployer())); - params.router = IEdgeFactory.RouterParams({ - externalResolvedVaults: new address[](0), - adapters: new IEdgeFactory.AdapterParams[](0) - }); + address[] memory vaults = new address[](2); - params.ltv = new IEdgeFactory.LTVParams[](1); - params.ltv[0] = IEdgeFactory.LTVParams({ - collateralVaultIndex: 0, - controllerVaultIndex: 1, - borrowLTV: BLTV, - liquidationLTV: LLTV - }); + // Escrow collateral vault: reuse the escrowed collateral perspective singleton if one + // already exists for the asset, otherwise deploy and verify it in the perspective + EscrowedCollateralPerspective escrowedCollateralPerspective = + EscrowedCollateralPerspective(peripheryAddresses.escrowedCollateralPerspective); + vaults[0] = escrowedCollateralPerspective.singletonLookup(token); + if (vaults[0] == address(0)) { + vaults[0] = GenericFactory(coreAddresses.eVaultFactory).createProxy( + address(0), true, abi.encodePacked(token, address(0), address(0)) + ); + IEVault(vaults[0]).setHookConfig(address(0), 0); + IEVault(vaults[0]).setGovernorAdmin(address(0)); + escrowedCollateralPerspective.perspectiveVerify(vaults[0], true); + } - params.unitOfAccount = token; + // Borrowable vault, using the token itself as the unit of account + vaults[1] = GenericFactory(coreAddresses.eVaultFactory).createProxy( + address(0), true, abi.encodePacked(token, address(router), token) + ); + IEVault(vaults[1]).setInterestRateModel(irm); + IEVault(vaults[1]).setLiquidationCoolOffTime(LIQ_COOL_OFF_TIME); + IEVault(vaults[1]).setMaxLiquidationDiscount(MAX_LIQ_DISCOUNT); + IEVault(vaults[1]).setHookConfig(address(0), 0); + + // Resolve both vaults in the router and renounce its governance + router.govSetResolvedVault(vaults[0], true); + router.govSetResolvedVault(vaults[1], true); + router.transferGovernance(address(0)); + + // Accept the escrow vault as collateral and renounce vault governance + IEVault(vaults[1]).setLTV(vaults[0], BLTV, LLTV, 0); + IEVault(vaults[1]).setGovernorAdmin(address(0)); - startBroadcast(); - (address router, address[] memory vaults) = IEdgeFactory(peripheryAddresses.edgeFactory).deploy(params); stopBroadcast(); - return (router, vaults); + return (address(router), vaults); } }