diff --git a/lib/euler-earn b/lib/euler-earn index 558b15b0..1c0b329e 160000 --- a/lib/euler-earn +++ b/lib/euler-earn @@ -1 +1 @@ -Subproject commit 558b15b0444750f742c85feda67ad6b9b851c4db +Subproject commit 1c0b329e864ebea843dcdc090c3fb92f2a96a200 diff --git a/script/02_PeripheryFactories.s.sol b/script/02_PeripheryFactories.s.sol index 1f2985c3..fb0cfd13 100644 --- a/script/02_PeripheryFactories.s.sol +++ b/script/02_PeripheryFactories.s.sol @@ -7,6 +7,7 @@ import {EulerRouterFactory} from "../src/EulerRouterFactory/EulerRouterFactory.s import {SnapshotRegistry} from "../src/SnapshotRegistry/SnapshotRegistry.sol"; import {EulerKinkIRMFactory} from "../src/IRMFactory/EulerKinkIRMFactory.sol"; import {EulerKinkyIRMFactory} from "../src/IRMFactory/EulerKinkyIRMFactory.sol"; +import {EulerFixedCyclicalBinaryIRMFactory} from "../src/IRMFactory/EulerFixedCyclicalBinaryIRMFactory.sol"; import {EulerIRMAdaptiveCurveFactory} from "../src/IRMFactory/EulerIRMAdaptiveCurveFactory.sol"; import {GovernorAccessControlEmergencyFactory} from "../src/GovernorFactory/GovernorAccessControlEmergencyFactory.sol"; import {CapRiskStewardFactory} from "../src/GovernorFactory/CapRiskStewardFactory.sol"; @@ -18,6 +19,7 @@ contract PeripheryFactories is ScriptUtils { address externalVaultRegistry; address kinkIRMFactory; address kinkyIRMFactory; + address fixedCyclicalBinaryIRMFactory; address adaptiveCurveIRMFactory; address irmRegistry; address governorAccessControlEmergencyFactory; @@ -40,6 +42,9 @@ contract PeripheryFactories is ScriptUtils { vm.serializeAddress("peripheryFactories", "externalVaultRegistry", deployedContracts.externalVaultRegistry); object = vm.serializeAddress("peripheryFactories", "kinkIRMFactory", deployedContracts.kinkIRMFactory); object = vm.serializeAddress("peripheryFactories", "kinkyIRMFactory", deployedContracts.kinkyIRMFactory); + object = vm.serializeAddress( + "peripheryFactories", "fixedCyclicalBinaryIRMFactory", deployedContracts.fixedCyclicalBinaryIRMFactory + ); object = vm.serializeAddress( "peripheryFactories", "adaptiveCurveIRMFactory", deployedContracts.adaptiveCurveIRMFactory ); @@ -64,6 +69,7 @@ contract PeripheryFactories is ScriptUtils { deployedContracts.externalVaultRegistry = address(new SnapshotRegistry(evc, getDeployer())); deployedContracts.kinkIRMFactory = address(new EulerKinkIRMFactory()); deployedContracts.kinkyIRMFactory = address(new EulerKinkyIRMFactory()); + deployedContracts.fixedCyclicalBinaryIRMFactory = address(new EulerFixedCyclicalBinaryIRMFactory()); deployedContracts.adaptiveCurveIRMFactory = address(new EulerIRMAdaptiveCurveFactory()); deployedContracts.irmRegistry = address(new SnapshotRegistry(evc, getDeployer())); deployedContracts.governorAccessControlEmergencyFactory = diff --git a/script/08_Lenses.s.sol b/script/08_Lenses.s.sol index b9ea10df..56c8a20d 100644 --- a/script/08_Lenses.s.sol +++ b/script/08_Lenses.s.sol @@ -19,8 +19,17 @@ contract Lenses is ScriptUtils { address oracleAdapterRegistry = vm.parseJsonAddress(json, ".oracleAdapterRegistry"); address kinkIRMFactory = vm.parseJsonAddress(json, ".kinkIRMFactory"); address adaptiveCurveIRMFactory = vm.parseJsonAddress(json, ".adaptiveCurveIRMFactory"); - - lenses = execute(eVaultFactory, oracleAdapterRegistry, kinkIRMFactory, adaptiveCurveIRMFactory); + address kinkyIRMFactory = vm.parseJsonAddress(json, ".kinkyIRMFactory"); + address fixedCyclicalBinaryIRMFactory = vm.parseJsonAddress(json, ".fixedCyclicalBinaryIRMFactory"); + + lenses = execute( + eVaultFactory, + oracleAdapterRegistry, + kinkIRMFactory, + adaptiveCurveIRMFactory, + kinkyIRMFactory, + fixedCyclicalBinaryIRMFactory + ); string memory object; object = vm.serializeAddress("lenses", "accountLens", lenses[0]); @@ -36,21 +45,34 @@ contract Lenses is ScriptUtils { address eVaultFactory, address oracleAdapterRegistry, address kinkIRMFactory, - address adaptiveCurveIRMFactory + address adaptiveCurveIRMFactory, + address kinkyIRMFactory, + address fixedCyclicalBinaryIRMFactory ) public broadcast returns (address[] memory lenses) { - lenses = execute(eVaultFactory, oracleAdapterRegistry, kinkIRMFactory, adaptiveCurveIRMFactory); + lenses = execute( + eVaultFactory, + oracleAdapterRegistry, + kinkIRMFactory, + adaptiveCurveIRMFactory, + kinkyIRMFactory, + fixedCyclicalBinaryIRMFactory + ); } function execute( address eVaultFactory, address oracleAdapterRegistry, address kinkIRMFactory, - address adaptiveCurveIRMFactory + address adaptiveCurveIRMFactory, + address kinkyIRMFactory, + address fixedCyclicalBinaryIRMFactory ) public returns (address[] memory lenses) { lenses = new address[](6); lenses[0] = address(new AccountLens()); lenses[1] = address(new OracleLens(oracleAdapterRegistry)); - lenses[2] = address(new IRMLens(kinkIRMFactory, adaptiveCurveIRMFactory)); + lenses[2] = address( + new IRMLens(kinkIRMFactory, adaptiveCurveIRMFactory, kinkyIRMFactory, fixedCyclicalBinaryIRMFactory) + ); lenses[3] = address(new UtilsLens(eVaultFactory, address(lenses[1]))); lenses[4] = address(new VaultLens(address(lenses[1]), address(lenses[3]), address(lenses[2]))); lenses[5] = address(new EulerEarnVaultLens(address(lenses[3]))); @@ -107,24 +129,34 @@ contract LensIRMDeployer is ScriptUtils { string memory json = getScriptFile(inputScriptFileName); address kinkIRMFactory = vm.parseJsonAddress(json, ".kinkIRMFactory"); address adaptiveCurveIRMFactory = vm.parseJsonAddress(json, ".adaptiveCurveIRMFactory"); + address kinkyIRMFactory = vm.parseJsonAddress(json, ".kinkyIRMFactory"); + address fixedCyclicalBinaryIRMFactory = vm.parseJsonAddress(json, ".fixedCyclicalBinaryIRMFactory"); - irmLens = execute(kinkIRMFactory, adaptiveCurveIRMFactory); + irmLens = execute(kinkIRMFactory, adaptiveCurveIRMFactory, kinkyIRMFactory, fixedCyclicalBinaryIRMFactory); string memory object; object = vm.serializeAddress("lens", "irmLens", irmLens); vm.writeJson(object, string.concat(vm.projectRoot(), "/script/", outputScriptFileName)); } - function deploy(address kinkIRMFactory, address adaptiveCurveIRMFactory) - public - broadcast - returns (address irmLens) - { - irmLens = execute(kinkIRMFactory, adaptiveCurveIRMFactory); + function deploy( + address kinkIRMFactory, + address adaptiveCurveIRMFactory, + address kinkyIRMFactory, + address fixedCyclicalBinaryIRMFactory + ) public broadcast returns (address irmLens) { + irmLens = execute(kinkIRMFactory, adaptiveCurveIRMFactory, kinkyIRMFactory, fixedCyclicalBinaryIRMFactory); } - function execute(address kinkIRMFactory, address adaptiveCurveIRMFactory) public returns (address irmLens) { - irmLens = address(new IRMLens(kinkIRMFactory, adaptiveCurveIRMFactory)); + function execute( + address kinkIRMFactory, + address adaptiveCurveIRMFactory, + address kinkyIRMFactory, + address fixedCyclicalBinaryIRMFactory + ) public returns (address irmLens) { + irmLens = address( + new IRMLens(kinkIRMFactory, adaptiveCurveIRMFactory, kinkyIRMFactory, fixedCyclicalBinaryIRMFactory) + ); } } diff --git a/script/20_EulerEarnFactory.s.sol b/script/20_EulerEarnFactory.s.sol index ba790f6e..ec5a2c52 100644 --- a/script/20_EulerEarnFactory.s.sol +++ b/script/20_EulerEarnFactory.s.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import {ScriptUtils} from "./utils/ScriptUtils.s.sol"; -contract EulerEarnFactory is ScriptUtils { - function run() public broadcast returns (address eulerEarnfactory) { +contract EulerEarnFactoryDeployer is ScriptUtils { + function run() public broadcast returns (address eulerEarnfactory, address eulerEarnPublicAllocator) { string memory inputScriptFileName = "21_EulerEarnFactory_input.json"; string memory outputScriptFileName = "21_EulerEarnFactory_output.json"; string memory json = getScriptFile(inputScriptFileName); @@ -13,19 +13,27 @@ contract EulerEarnFactory is ScriptUtils { address permit2 = vm.parseJsonAddress(json, ".permit2"); address perspective = vm.parseJsonAddress(json, ".perspective"); - eulerEarnfactory = execute(evc, permit2, perspective); + (eulerEarnfactory, eulerEarnPublicAllocator) = execute(evc, permit2, perspective); string memory object; object = vm.serializeAddress("factory", "eulerEarnfactory", eulerEarnfactory); + object = vm.serializeAddress("publicAllocator", "eulerEarnPublicAllocator", eulerEarnPublicAllocator); vm.writeJson(object, string.concat(vm.projectRoot(), "/script/", outputScriptFileName)); } - function deploy(address evc, address permit2, address perspective) public broadcast returns (address factory) { - factory = execute(evc, permit2, perspective); + function deploy(address evc, address permit2, address perspective) + public + broadcast + returns (address factory, address publicAllocator) + { + (factory, publicAllocator) = execute(evc, permit2, perspective); } - function execute(address evc, address permit2, address perspective) public returns (address factory) { + function execute(address evc, address permit2, address perspective) + public + returns (address factory, address publicAllocator) + { bytes memory bytecode = abi.encodePacked( vm.getCode("out-euler-earn/EulerEarnFactory.sol/EulerEarnFactory.json"), abi.encode(getDeployer(), evc, permit2, perspective) @@ -33,5 +41,11 @@ contract EulerEarnFactory is ScriptUtils { assembly { factory := create(0, add(bytecode, 0x20), mload(bytecode)) } + + bytecode = + abi.encodePacked(vm.getCode("out-euler-earn/PublicAllocator.sol/PublicAllocator.json"), abi.encode(evc)); + assembly { + publicAllocator := create(0, add(bytecode, 0x20), mload(bytecode)) + } } } diff --git a/script/50_CoreAndPeriphery.s.sol b/script/50_CoreAndPeriphery.s.sol index fcfbb1e3..fee9c68b 100644 --- a/script/50_CoreAndPeriphery.s.sol +++ b/script/50_CoreAndPeriphery.s.sol @@ -34,7 +34,7 @@ import {EVaultFactoryGovernorDeployer, TimelockControllerDeployer} from "./12_Go import {TermsOfUseSignerDeployer} from "./13_TermsOfUseSigner.s.sol"; import {OFTAdapterUpgradeableDeployer, MintBurnOFTAdapterDeployer} from "./14_OFT.s.sol"; import {EdgeFactoryDeployer} from "./15_EdgeFactory.s.sol"; -import {EulerEarnFactory} from "./20_EulerEarnFactory.s.sol"; +import {EulerEarnFactoryDeployer} from "./20_EulerEarnFactory.s.sol"; import {EulerSwapImplementationDeployer} from "./21_EulerSwapImplementation.s.sol"; import {EulerSwapFactoryDeployer} from "./22_EulerSwapFactory.s.sol"; import {EulerSwapPeripheryDeployer} from "./23_EulerSwapPeriphery.s.sol"; @@ -99,9 +99,6 @@ contract CoreAndPeriphery is BatchBuilder, SafeMultisendBuilder { int256 adjustmentSpeed; } - mapping(uint256 chainId => bool isHarvestCoolDownCheckOn) internal EULER_EARN_HARVEST_COOL_DOWN_CHECK_ON; - uint256[1] internal EULER_EARN_HARVEST_COOL_DOWN_CHECK_ON_CHAIN_IDS = [1]; - address internal constant BURN_ADDRESS = address(0xdead); uint256 internal constant EUL_HUB_CHAIN_ID = 1; uint8 internal constant EUL_DECIMALS = 18; @@ -138,11 +135,6 @@ contract CoreAndPeriphery is BatchBuilder, SafeMultisendBuilder { AdaptiveCurveIRMParams[] internal DEFAULT_ADAPTIVE_CURVE_IRMS_PARAMS; constructor() { - for (uint256 i = 0; i < EULER_EARN_HARVEST_COOL_DOWN_CHECK_ON_CHAIN_IDS.length; ++i) { - uint256 chainId = EULER_EARN_HARVEST_COOL_DOWN_CHECK_ON_CHAIN_IDS[i]; - EULER_EARN_HARVEST_COOL_DOWN_CHECK_ON[chainId] = true; - } - for (uint256 i = 0; i < IRM_INITIAL_RATES_AT_TARGET.length; ++i) { DEFAULT_ADAPTIVE_CURVE_IRMS_PARAMS.push( AdaptiveCurveIRMParams({ @@ -472,7 +464,10 @@ contract CoreAndPeriphery is BatchBuilder, SafeMultisendBuilder { console.log("- OFT Adapter already deployed. Skipping..."); } - if (containsOftHubChainId(block.chainid) && bridgeAddresses.oftAdapter != address(0)) { + if ( + containsOftHubChainId(block.chainid) && bridgeAddresses.oftAdapter != address(0) + && !getSkipOFTHubChainConfig() + ) { console.log("+ Attempting to configure OFT Adapter on chain %s", block.chainid); LayerZeroUtil lzUtil = new LayerZeroUtil(); @@ -661,6 +656,7 @@ contract CoreAndPeriphery is BatchBuilder, SafeMultisendBuilder { && peripheryAddresses.oracleAdapterRegistry == address(0) && peripheryAddresses.externalVaultRegistry == address(0) && peripheryAddresses.kinkIRMFactory == address(0) && peripheryAddresses.kinkyIRMFactory == address(0) + && peripheryAddresses.fixedCyclicalBinaryIRMFactory == address(0) && peripheryAddresses.adaptiveCurveIRMFactory == address(0) && peripheryAddresses.irmRegistry == address(0) && peripheryAddresses.governorAccessControlEmergencyFactory == address(0) && peripheryAddresses.capRiskStewardFactory == address(0) @@ -674,6 +670,7 @@ contract CoreAndPeriphery is BatchBuilder, SafeMultisendBuilder { peripheryAddresses.externalVaultRegistry = peripheryContracts.externalVaultRegistry; peripheryAddresses.kinkIRMFactory = peripheryContracts.kinkIRMFactory; peripheryAddresses.kinkyIRMFactory = peripheryContracts.kinkyIRMFactory; + peripheryAddresses.fixedCyclicalBinaryIRMFactory = peripheryContracts.fixedCyclicalBinaryIRMFactory; peripheryAddresses.adaptiveCurveIRMFactory = peripheryContracts.adaptiveCurveIRMFactory; peripheryAddresses.irmRegistry = peripheryContracts.irmRegistry; peripheryAddresses.governorAccessControlEmergencyFactory = @@ -859,13 +856,13 @@ contract CoreAndPeriphery is BatchBuilder, SafeMultisendBuilder { console.log("- EulerUngovernedNzxPerspective already deployed. Skipping..."); } - if (coreAddresses.eulerEarnFactory == address(0)) { - console.log("+ Deploying EulerEarn factory..."); - EulerEarnFactory deployer = new EulerEarnFactory(); - coreAddresses.eulerEarnFactory = + if (coreAddresses.eulerEarnFactory == address(0) && peripheryAddresses.eulerEarnPublicAllocator == address(0)) { + console.log("+ Deploying EulerEarn factory and public allocator..."); + EulerEarnFactoryDeployer deployer = new EulerEarnFactoryDeployer(); + (coreAddresses.eulerEarnFactory, peripheryAddresses.eulerEarnPublicAllocator) = deployer.deploy(coreAddresses.evc, coreAddresses.permit2, peripheryAddresses.evkFactoryPerspective); } else { - console.log("- EulerEarn factory already deployed. Skipping..."); + console.log("- EulerEarn factory and public allocator already deployed. Skipping..."); if (vm.isDir("out-euler-earn")) vm.removeDir("out-euler-earn", true); } @@ -927,8 +924,12 @@ contract CoreAndPeriphery is BatchBuilder, SafeMultisendBuilder { if (lensAddresses.irmLens == address(0)) { console.log("+ Deploying LensIRM..."); LensIRMDeployer deployer = new LensIRMDeployer(); - lensAddresses.irmLens = - deployer.deploy(peripheryAddresses.kinkIRMFactory, peripheryAddresses.adaptiveCurveIRMFactory); + lensAddresses.irmLens = deployer.deploy( + peripheryAddresses.kinkIRMFactory, + peripheryAddresses.adaptiveCurveIRMFactory, + peripheryAddresses.kinkyIRMFactory, + peripheryAddresses.fixedCyclicalBinaryIRMFactory + ); } else { console.log("- LensIRM already deployed. Skipping..."); } diff --git a/script/interactiveDeployment.sh b/script/interactiveDeployment.sh index 75a5c39c..689cdf7f 100755 --- a/script/interactiveDeployment.sh +++ b/script/interactiveDeployment.sh @@ -37,7 +37,7 @@ if ! script/utils/checkEnvironment.sh "$@"; then exit 1 fi -eulerEarnCompilerOptions="--via-ir --optimize --optimizer-runs 800 --use 0.8.26 --out out-euler-earn" +eulerEarnCompilerOptions="--via-ir --optimize --optimizer-runs 200 --use 0.8.26 --out out-euler-earn" eulerSwapCompilerOptions="--optimize --optimizer-runs 1000000 --use 0.8.27 --out out-euler-swap" while true; do @@ -779,10 +779,16 @@ while true; do --arg eVaultFactory "$eVaultFactory" \ --arg oracleAdapterRegistry "$oracle_adapter_registry" \ --arg kinkIRMFactory "$kink_irm_factory" \ + --arg adaptiveCurveIRMFactory "$adaptive_curve_irm_factory" \ + --arg kinkyIRMFactory "$kinky_irm_factory" \ + --arg fixedCyclicalBinaryIRMFactory "$fixed_cyclical_binary_irm_factory" \ '{ eVaultFactory: $eVaultFactory, oracleAdapterRegistry: $oracleAdapterRegistry, - kinkIRMFactory: $kinkIRMFactory + kinkIRMFactory: $kinkIRMFactory, + adaptiveCurveIRMFactory: $adaptiveCurveIRMFactory, + kinkyIRMFactory: $kinkyIRMFactory, + fixedCyclicalBinaryIRMFactory: $fixedCyclicalBinaryIRMFactory }' --indent 4 > script/${jsonName}_input.json ;; 1) diff --git a/script/production/ConfigWhitelistGovernedPerspective.sh b/script/production/ConfigWhitelistGovernedPerspective.sh index 6d3db13b..0c2770fe 100755 --- a/script/production/ConfigWhitelistGovernedPerspective.sh +++ b/script/production/ConfigWhitelistGovernedPerspective.sh @@ -16,6 +16,12 @@ eval 'set -- $SCRIPT_ARGS' addresses_dir_path="${ADDRESSES_DIR_PATH%/}/$(cast chain-id --rpc-url $DEPLOYMENT_RPC_URL)" evc=$(jq -r '.evc' "$addresses_dir_path/CoreAddresses.json") +if [[ "$@" != *"--earn"* && "$@" != *"--evk"* ]]; then + echo "Error: Either --earn or --evk option must be provided" + echo "Usage: $0 [--earn|--evk] [other_options...]" + exit 1 +fi + if [[ "$@" == *"--earn"* ]]; then governed_perspective=$(jq -r '.eulerEarnGovernedPerspective' "$addresses_dir_path/PeripheryAddresses.json") else @@ -100,6 +106,7 @@ items="[" while IFS=, read -r -a columns || [ -n "$columns" ]; do vault="${columns[0]}" + label="${columns[1]}" whitelist="${columns[2]}" if [[ "$vault" == "Vault" ]]; then @@ -110,20 +117,20 @@ while IFS=, read -r -a columns || [ -n "$columns" ]; do if [[ "$whitelist" == "Yes" ]]; then if [[ $isVerified == *false* ]]; then - echo "Adding 'perspectiveVerify' batch item for vault $vault" + echo "Adding 'perspectiveVerify' batch item for vault $vault ($label)" items+="($governed_perspective,$onBehalfOf,0,$(cast calldata "perspectiveVerify(address,bool)" $vault true))," elif [[ "$verbose" == "--verbose" ]]; then - echo "Vault $vault is already verified. Skipping..." + echo "Vault $vault ($label) is already verified. Skipping..." fi elif [[ "$whitelist" == "No" ]]; then if [[ $isVerified == *true* ]]; then - echo "Adding 'perspectiveUnverify' batch item for vault $vault" + echo "Adding 'perspectiveUnverify' batch item for vault $vault ($label)" items+="($governed_perspective,$onBehalfOf,0,$(cast calldata "perspectiveUnverify(address)" $vault))," elif [[ "$verbose" == "--verbose" ]]; then - echo "Vault $vault is not verified. Skipping..." + echo "Vault $vault ($label) is not verified. Skipping..." fi else - echo "Invalid Whitelist value for vault $vault. Skipping..." + echo "Invalid Whitelist value for vault $vault ($label). Skipping..." fi done < <(tr -d '\r' < "$csv_file") diff --git a/script/production/CustomScripts.s.sol b/script/production/CustomScripts.s.sol index 257b86cd..2884b69d 100644 --- a/script/production/CustomScripts.s.sol +++ b/script/production/CustomScripts.s.sol @@ -2,14 +2,16 @@ pragma solidity ^0.8.0; -import {BatchBuilder} from "../utils/ScriptUtils.s.sol"; +import {ScriptUtils, BatchBuilder, IEVC, IEVault, console} from "../utils/ScriptUtils.s.sol"; +import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; import {AccessControl} from "openzeppelin-contracts/access/AccessControl.sol"; import {TimelockController} from "openzeppelin-contracts/governance/TimelockController.sol"; import {IGovernance} from "evk/EVault/IEVault.sol"; -import {SafeTransaction} from "../utils/SafeUtils.s.sol"; +import {SafeTransaction, SafeMultisendBuilder} from "../utils/SafeUtils.s.sol"; import {FactoryGovernor} from "../../src/Governor/FactoryGovernor.sol"; import {CapRiskSteward} from "../../src/Governor/CapRiskSteward.sol"; import {GovernorAccessControlEmergency} from "../../src/Governor/GovernorAccessControlEmergency.sol"; +import {LayerZeroSendEUL} from "../utils/LayerZeroUtils.s.sol"; abstract contract CustomScriptBase is BatchBuilder { function run() public { @@ -20,6 +22,206 @@ abstract contract CustomScriptBase is BatchBuilder { function execute() public virtual {} } +contract BridgeEULToLabsMultisig is ScriptUtils, SafeMultisendBuilder { + function run(uint256 dstChainId, uint256 amountNoDecimals) public { + uint256[] memory dstChainIds = new uint256[](1); + uint256[] memory amountsNoDecimals = new uint256[](1); + dstChainIds[0] = dstChainId; + amountsNoDecimals[0] = amountNoDecimals; + execute(dstChainIds, amountsNoDecimals); + } + + function run(uint256[] memory dstChainIds, uint256[] memory amountsNoDecimals) public { + require( + dstChainIds.length == amountsNoDecimals.length, + "dstChainIds and amountsNoDecimals must have the same length" + ); + execute(dstChainIds, amountsNoDecimals); + } + + function execute(uint256[] memory dstChainIds, uint256[] memory amountsNoDecimals) public { + LayerZeroSendEUL util = new LayerZeroSendEUL(); + address safe = getSafe(false); + + for (uint256 i = 0; i < dstChainIds.length; ++i) { + uint256 dstChainId = dstChainIds[i]; + uint256 amount = amountsNoDecimals[i] * 1e18; + address dstAddress = + deserializeMultisigAddresses(getAddressesJson("MultisigAddresses.json", dstChainId)).labs; + + if (safe == address(0)) { + util.run(dstChainId, dstAddress, amount); + } else { + (address to, uint256 value, bytes memory rawCalldata) = + util.getSendCalldata(dstChainId, dstAddress, amount, 1e4); + addMultisendItem(tokenAddresses.EUL, abi.encodeCall(IERC20.approve, (to, amount))); + addMultisendItem(to, value, rawCalldata); + } + } + + if (multisendItemExists()) executeMultisend(safe, safeNonce++, false); + } +} + +contract MigratePosition is BatchBuilder { + function run() public { + uint8[] memory sourceIds = new uint8[](1); + uint8[] memory destinationIds = new uint8[](1); + + sourceIds[0] = getSourceAccountId(); + destinationIds[0] = getDestinationAccountId(); + + execute(sourceIds, destinationIds); + } + + function run(uint8[] calldata sourceIds, uint8[] calldata destinationIds) public { + execute(sourceIds, destinationIds); + } + + function execute(uint8[] memory sourceIds, uint8[] memory destinationIds) public { + require( + sourceIds.length == destinationIds.length && sourceIds.length > 0, + "sourceIds and destinationIds must have the same length and be less than or equal to 5" + ); + + address sourceWallet = getSourceWallet(); + bytes19 sourceWalletPrefix = IEVC(coreAddresses.evc).getAddressPrefix(sourceWallet); + address destinationWallet = getDestinationWallet(); + + uint256 bitfield; + for (uint8 i = 0; i < sourceIds.length; ++i) { + bitfield |= 1 << sourceIds[i]; + } + + for (uint8 i = 0; i < sourceIds.length; ++i) { + _migratePosition(sourceWallet, sourceIds[i], destinationWallet, destinationIds[i]); + } + + string memory result = string.concat( + "IMPORTANT: before proceeding, you must trust the destination wallet ", + vm.toString(destinationWallet), + "!\n\n" + ); + result = string.concat(result, "Step 1: give control over your account to the destination wallet\n"); + result = string.concat( + result, + "Go to the block explorer dedicated to your network and paste the EVC address: ", + vm.toString(coreAddresses.evc), + "\n" + ); + result = string.concat( + result, + "Click 'Contract' and then 'Write Contract'. Find 'setOperator' function. Paste the following input data:\n" + ); + result = string.concat(result, " setOperator/payableAmount: 0\n"); + result = string.concat(result, " addressPrefix: ", _substring(vm.toString(sourceWalletPrefix), 0, 40), "\n"); + result = string.concat(result, " operator: ", vm.toString(destinationWallet), "\n"); + result = string.concat(result, " operatorBitField: ", vm.toString(bitfield), "\n"); + result = string.concat(result, "Connect your source wallet, click 'Write' and execute the transaction.\n\n"); + result = string.concat(result, "Step 2: pull the position from the source account to the destination account\n"); + result = string.concat( + result, + "Go to the block explorer dedicated to your network and paste the EVC address: ", + vm.toString(coreAddresses.evc), + "\n" + ); + result = string.concat( + result, + "Click 'Contract' and then 'Write Contract'. Find 'batch' function. Paste the following input data:\n" + ); + result = string.concat(result, " batch/payableAmount: 0\n"); + result = string.concat(result, " items: ", toString(getBatchItems()), "\n"); + result = string.concat(result, "Connect your destination wallet, click 'Write' and execute the transaction.\n"); + + console.log(result); + vm.writeFile(string.concat(vm.projectRoot(), "/script/MigrationInstruction.txt"), result); + + // simulation + vm.prank(sourceWallet); + IEVC(coreAddresses.evc).setOperator(sourceWalletPrefix, destinationWallet, bitfield); + + if (isBatchViaSafe()) { + executeBatchViaSafe(false); + } else { + dumpBatch(destinationWallet); + executeBatchPrank(destinationWallet); + } + } + + function _migratePosition( + address sourceWallet, + uint8 sourceAccountId, + address destinationWallet, + uint8 destinationAccountId + ) internal { + address sourceAccount = address(uint160(sourceWallet) ^ sourceAccountId); + address destinationAccount = address(uint160(destinationWallet) ^ destinationAccountId); + address[] memory collaterals = IEVC(coreAddresses.evc).getCollaterals(sourceAccount); + address[] memory controllers = IEVC(coreAddresses.evc).getControllers(sourceAccount); + + for (uint256 i = 0; i < collaterals.length; ++i) { + uint256 amount = IEVault(collaterals[i]).balanceOf(sourceAccount); + if (amount == 0) continue; + + addBatchItem( + coreAddresses.evc, + address(0), + abi.encodeCall(IEVC.enableCollateral, (destinationAccount, collaterals[i])) + ); + addBatchItem( + collaterals[i], + sourceAccount, + abi.encodeCall(IEVault(collaterals[i]).transfer, (destinationAccount, amount)) + ); + addBatchItem( + coreAddresses.evc, address(0), abi.encodeCall(IEVC.disableCollateral, (sourceAccount, collaterals[i])) + ); + } + + for (uint256 i = 0; i < controllers.length; ++i) { + if (IEVault(controllers[i]).debtOf(sourceAccount) == 0) continue; + + addBatchItem( + coreAddresses.evc, + address(0), + abi.encodeCall(IEVC.enableController, (destinationAccount, controllers[i])) + ); + addBatchItem( + controllers[i], + destinationAccount, + abi.encodeCall(IEVault(controllers[i]).pullDebt, (type(uint256).max, sourceAccount)) + ); + addBatchItem(controllers[i], sourceAccount, abi.encodeCall(IEVault(controllers[i]).disableController, ())); + } + + addBatchItem( + coreAddresses.evc, + address(0), + abi.encodeCall(IEVC.setAccountOperator, (sourceAccount, destinationWallet, false)) + ); + } +} + +contract MergeSafeBatchBuilderFiles is CustomScriptBase, SafeMultisendBuilder { + function execute() public override { + address safe = getSafe(); + string memory basePath = string.concat( + vm.projectRoot(), "/", getPath(), "/SafeBatchBuilder_", vm.toString(safeNonce), "_", vm.toString(safe), "_" + ); + + for (uint256 i = 0; vm.exists(string.concat(basePath, vm.toString(i), ".json")); i++) { + string memory json = vm.readFile(string.concat(basePath, vm.toString(i), ".json")); + address target = vm.parseJsonAddress(json, ".transactions[0].to"); + uint256 value = vm.parseJsonUint(json, ".transactions[0].value"); + bytes memory data = vm.parseJsonBytes(json, ".transactions[0].data"); + + addMultisendItem(target, value, data); + } + + executeMultisend(safe, safeNonce++); + } +} + contract UnpauseEVaultFactory is CustomScriptBase { function execute() public override { SafeTransaction transaction = new SafeTransaction(); diff --git a/script/production/ExecuteSolidityScript.sh b/script/production/ExecuteSolidityScript.sh index ff987b7a..43e310b0 100755 --- a/script/production/ExecuteSolidityScript.sh +++ b/script/production/ExecuteSolidityScript.sh @@ -73,6 +73,13 @@ for rpc_url in "${rpc_urls_array[@]}"; do mv "$json_file" "$deployment_dir/output/${jsonFileName%.json}_$counter.json" done + for txt_file in script/*.txt; do + txtFileName=$(basename "$txt_file") + counter=$(script/utils/getFileNameCounter.sh "$deployment_dir/output/$txtFileName") + + mv "$txt_file" "$deployment_dir/output/${txtFileName%.txt}_$counter.txt" + done + for csv_file in script/*.csv; do csvFileName=$(basename "$csv_file") counter=$(script/utils/getFileNameCounter.sh "$deployment_dir/output/$csvFileName") diff --git a/script/production/ManageClusterBase.s.sol b/script/production/ManageClusterBase.s.sol index bd4bef40..35163065 100644 --- a/script/production/ManageClusterBase.s.sol +++ b/script/production/ManageClusterBase.s.sol @@ -45,7 +45,9 @@ abstract contract ManageClusterBase is BatchBuilder { bool forceZeroGovernors; mapping(address asset => string provider) oracleProviders; mapping(address asset => uint256 supplyCapNoDecimals) supplyCaps; + mapping(address asset => bool supplyCapEncoded) supplyCapEncoded; mapping(address asset => uint256 borrowCapNoDecimals) borrowCaps; + mapping(address asset => bool borrowCapEncoded) borrowCapEncoded; mapping(address asset => address feeReceiverOverride) feeReceiverOverride; mapping(address asset => uint16 interestFeeOverride) interestFeeOverride; mapping(address asset => uint16 maxLiquidationDiscountOverride) maxLiquidationDiscountOverride; @@ -83,8 +85,8 @@ abstract contract ManageClusterBase is BatchBuilder { defineCluster(); loadCluster(); configureCluster(); - encodeAmountCaps(cluster.assets, cluster.supplyCaps); - encodeAmountCaps(cluster.assets, cluster.borrowCaps); + encodeAmountCaps(cluster.assets, cluster.supplyCaps, cluster.supplyCapEncoded); + encodeAmountCaps(cluster.assets, cluster.borrowCaps, cluster.borrowCapEncoded); checkClusterDataSanity(); simulatePendingTransactions(); @@ -205,30 +207,33 @@ abstract contract ManageClusterBase is BatchBuilder { // desired. // recognize potentially pending transactions by looking up pendingResolvedVaults and // pendingConfiguredAdapters mappings - { - address oracleRouter = cluster.oracleRouters[i]; - address unitOfAccount = IEVault(vault).unitOfAccount(); - (address base, address adapter,) = - computeRouterConfiguration(asset, unitOfAccount, cluster.oracleProviders[asset]); - // in case the vault asset is a valid external vault, resolve it in the router - if ( - asset != base && !pendingResolvedVaults[oracleRouter][asset][base] - && isValidOracleRouter(oracleRouter) && EulerRouter(oracleRouter).resolvedVaults(asset) != base - ) { - govSetResolvedVault(oracleRouter, asset, true); - pendingResolvedVaults[oracleRouter][asset][base] = true; - } - - // configure the oracle for the vault asset or the asset of the vault asset - if ( - !pendingConfiguredAdapters[oracleRouter][base][unitOfAccount] && isValidOracleRouter(oracleRouter) - && EulerRouter(oracleRouter).getConfiguredOracle(base, unitOfAccount) != adapter - ) { - govSetConfig(oracleRouter, base, unitOfAccount, adapter); - pendingConfiguredAdapters[oracleRouter][base][unitOfAccount] = true; - } - } + // COMMENTED OUT SO THAT THE ROUTER IS ONLY CONFIGURED WHEN ACTUALLY NEEDED + //{ + // address oracleRouter = cluster.oracleRouters[i]; + // address unitOfAccount = IEVault(vault).unitOfAccount(); + // (address base, address adapter,) = + // computeRouterConfiguration(asset, unitOfAccount, cluster.oracleProviders[asset]); + // + // // in case the vault asset is a valid external vault, resolve it in the router + // if ( + // asset != base && !pendingResolvedVaults[oracleRouter][asset][base] + // && isValidOracleRouter(oracleRouter) && EulerRouter(oracleRouter).resolvedVaults(asset) != + // base + // ) { + // govSetResolvedVault(oracleRouter, asset, true); + // pendingResolvedVaults[oracleRouter][asset][base] = true; + // } + // + // // configure the oracle for the vault asset or the asset of the vault asset + // if ( + // !pendingConfiguredAdapters[oracleRouter][base][unitOfAccount] && isValidOracleRouter(oracleRouter) + // && EulerRouter(oracleRouter).getConfiguredOracle(base, unitOfAccount) != adapter + // ) { + // govSetConfig(oracleRouter, base, unitOfAccount, adapter); + // pendingConfiguredAdapters[oracleRouter][base][unitOfAccount] = true; + // } + //} // configure the vault by checking if current configuration differs from desired. // recognize potential overrides applicable per asset @@ -519,32 +524,35 @@ abstract contract ManageClusterBase is BatchBuilder { // configure the oracle router for the collateral before setting the LTV. recognize potentially pending // transactions by looking up pendingResolvedVaults and pendingConfiguredAdapters mappings - // resolve the collateral vault in the router to be able to convert shares to assets - if ( - !pendingResolvedVaults[oracleRouter][collateral][collateralAsset] && isValidOracleRouter(oracleRouter) - && EulerRouter(oracleRouter).resolvedVaults(collateral) != collateralAsset - ) { - govSetResolvedVault(oracleRouter, collateral, true); - pendingResolvedVaults[oracleRouter][collateral][collateralAsset] = true; - } + if (currentBorrowLTV > 0 || borrowLTV > 0 || liquidationLTV > 0 || targetLiquidationLTV > 0) { + // resolve the collateral vault in the router to be able to convert shares to assets + if ( + !pendingResolvedVaults[oracleRouter][collateral][collateralAsset] + && isValidOracleRouter(oracleRouter) + && EulerRouter(oracleRouter).resolvedVaults(collateral) != collateralAsset + ) { + govSetResolvedVault(oracleRouter, collateral, true); + pendingResolvedVaults[oracleRouter][collateral][collateralAsset] = true; + } - // in case the collateral vault asset is a valid external vault, resolve it in the router - if ( - collateralAsset != base && !pendingResolvedVaults[oracleRouter][collateralAsset][base] - && isValidOracleRouter(oracleRouter) - && EulerRouter(oracleRouter).resolvedVaults(collateralAsset) != base - ) { - govSetResolvedVault(oracleRouter, collateralAsset, true); - pendingResolvedVaults[oracleRouter][collateralAsset][base] = true; - } + // in case the collateral vault asset is a valid external vault, resolve it in the router + if ( + collateralAsset != base && !pendingResolvedVaults[oracleRouter][collateralAsset][base] + && isValidOracleRouter(oracleRouter) + && EulerRouter(oracleRouter).resolvedVaults(collateralAsset) != base + ) { + govSetResolvedVault(oracleRouter, collateralAsset, true); + pendingResolvedVaults[oracleRouter][collateralAsset][base] = true; + } - // configure the oracle for the collateral vault asset or the asset of the collateral vault asset - if ( - !pendingConfiguredAdapters[oracleRouter][base][unitOfAccount] && isValidOracleRouter(oracleRouter) - && EulerRouter(oracleRouter).getConfiguredOracle(base, unitOfAccount) != adapter - ) { - govSetConfig(oracleRouter, base, unitOfAccount, adapter); - pendingConfiguredAdapters[oracleRouter][base][unitOfAccount] = true; + // configure the oracle for the collateral vault asset or the asset of the collateral vault asset + if ( + !pendingConfiguredAdapters[oracleRouter][base][unitOfAccount] && isValidOracleRouter(oracleRouter) + && EulerRouter(oracleRouter).getConfiguredOracle(base, unitOfAccount) != adapter + ) { + govSetConfig(oracleRouter, base, unitOfAccount, adapter); + pendingConfiguredAdapters[oracleRouter][base][unitOfAccount] = true; + } } // disregard the current liquidation LTV if currently ramping down, only compare target LTVs to figure out @@ -779,6 +787,49 @@ abstract contract ManageClusterBase is BatchBuilder { } } + if (getCheckPhasedOutVaults()) { + for (uint256 i = 0; i < cluster.vaults.length; ++i) { + bool notPhasedOut; + + for (uint256 j = 0; j < cluster.vaults.length; ++j) { + if (IEVault(cluster.vaults[i]).LTVLiquidation(cluster.vaults[j]) > 0) { + notPhasedOut = true; + break; + } + } + + for (uint256 j = 0; j < cluster.vaults.length; ++j) { + if (IEVault(cluster.vaults[j]).LTVLiquidation(cluster.vaults[i]) > 0) { + notPhasedOut = true; + break; + } + } + + if (!notPhasedOut) { + console.log("Phased out vault found: %s %s", cluster.vaults[i], IEVault(cluster.vaults[i]).symbol()); + } + } + + for (uint256 i = 0; i < cluster.externalVaults.length; ++i) { + bool notPhasedOut; + + for (uint256 j = 0; j < cluster.vaults.length; ++j) { + if (IEVault(cluster.vaults[j]).LTVLiquidation(cluster.externalVaults[i]) > 0) { + notPhasedOut = true; + break; + } + } + + if (!notPhasedOut) { + console.log( + "Phased out external vault found: %s %s", + cluster.externalVaults[i], + IEVault(cluster.externalVaults[i]).symbol() + ); + } + } + } + require(bytes(cluster.clusterAddressesPath).length != 0, "Invalid cluster addresses path"); require( cluster.forceZeroGovernors diff --git a/script/production/arbitrum/clusters/ArbitrumCluster.json b/script/production/arbitrum/clusters/ArbitrumCluster.json index 4ee8c05f..73024da4 100644 --- a/script/production/arbitrum/clusters/ArbitrumCluster.json +++ b/script/production/arbitrum/clusters/ArbitrumCluster.json @@ -1,15 +1,25 @@ { "externalVaults": [], "irms": [ - "0x47842E428bA5553480227125013621e3E5A237b5", - "0x47842E428bA5553480227125013621e3E5A237b5", + "0xf980E17003af46173c6e5a1d73033d407dD759B7", + "0xf980E17003af46173c6e5a1d73033d407dD759B7", + "0xAd02ab868fc9d5CA4e4db8dc8caE6913b571Cb86", + "0xAd02ab868fc9d5CA4e4db8dc8caE6913b571Cb86", "0x91FBEAc79167d574B8b0D9E00cb35143c4CB84E2", "0xF7c774aCFA136F527287Dbc05477c015Ee6ED2C9", "0xF7c774aCFA136F527287Dbc05477c015Ee6ED2C9", + "0xF7c774aCFA136F527287Dbc05477c015Ee6ED2C9", + "0xF7c774aCFA136F527287Dbc05477c015Ee6ED2C9", + "0xF7c774aCFA136F527287Dbc05477c015Ee6ED2C9", "0xabD4606a6643EE58E42f8CdF65F47cA201Cf703f", "0x9ca9d2f95D0fBf4Aa5ff16ad2B3ebAc04C9bE2Dd" ], "oracleRouters": [ + "0x94B6924796CcC98e5237615F8710Ef5732190F66", + "0x94B6924796CcC98e5237615F8710Ef5732190F66", + "0x94B6924796CcC98e5237615F8710Ef5732190F66", + "0x94B6924796CcC98e5237615F8710Ef5732190F66", + "0x94B6924796CcC98e5237615F8710Ef5732190F66", "0x94B6924796CcC98e5237615F8710Ef5732190F66", "0x94B6924796CcC98e5237615F8710Ef5732190F66", "0x94B6924796CcC98e5237615F8710Ef5732190F66", @@ -22,9 +32,14 @@ "vaults": [ "0x0a1eCC5Fe8C9be3C809844fcBe615B46A869b899", "0x37512F45B4ba8808910632323b73783Ca938CD51", + "0x0EE8D628411F446BFbbe08BDeF53E42414C8fBC4", + "0xa7a9B773f139010f284E825a74060648d91dE37a", "0x78E3E051D32157AACD550fBB78458762d8f7edFF", "0xA8616E4D9f3f0aa01aff1d7c3b66249f8a5f1A58", "0x5A8294CE02908B1da68c6c39695c9b0FbaF7675d", + "0xE96e07C16661744836a742Ef2090F11e84a86f4F", + "0xDBD974Eb5360d053ea0c56B4DaCF4A9D3E894Ee2", + "0xaA525D3142A5BDD3E55E8e983D3789b88F2FEB8f", "0x889E1c458B2469b70aCcdfb5B59726dC1668896C", "0x7eD866D2D66c3149FaFE854C30C68a8BA7ceE8B9" ] diff --git a/script/production/arbitrum/clusters/ArbitrumCluster.s.sol b/script/production/arbitrum/clusters/ArbitrumCluster.s.sol index af5fa671..99a71317 100644 --- a/script/production/arbitrum/clusters/ArbitrumCluster.s.sol +++ b/script/production/arbitrum/clusters/ArbitrumCluster.s.sol @@ -17,9 +17,14 @@ contract Cluster is ManageCluster { cluster.assets = [ USDC, USDT0, + sUSDS, + sUSDC, WETH, wstETH, weETH, + rsETH, + tETH, + ezETH, WBTC, ARB ]; @@ -60,27 +65,42 @@ contract Cluster is ManageCluster { // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form of a string. cluster.oracleProviders[USDC ] = "0x3CD81aee1c41757B88961572BfD192cBF2127f37"; cluster.oracleProviders[USDT0 ] = "0xbBC0166f5F14e9C4970c87bd5336e19Bc530FD74"; + cluster.oracleProviders[sUSDS ] = "0x5939ee098eb6d411c3727b78ee665771f5cb0501"; + cluster.oracleProviders[sUSDC ] = "ExternalVault|0x3CD81aee1c41757B88961572BfD192cBF2127f37"; cluster.oracleProviders[WETH ] = "0x6C1212B14E190a5eB91B1c8cc2f6f4623476862C"; cluster.oracleProviders[wstETH] = "0x1B9405C4742DF2fB0a2fC838fA08c4FE03300702"; cluster.oracleProviders[weETH ] = "0x4F22d594a852DD3788Ba605A4786946334881492"; + cluster.oracleProviders[rsETH ] = "0xB84F6D77C823980E6fa40fe474c86138ECBb97D1"; + cluster.oracleProviders[tETH ] = "0x5CAbb4FC26Db9d6b028dE7a9ae05164671d51D7a"; + cluster.oracleProviders[ezETH ] = "0x9C5321AB283283B75A83422e996234a6Cfa436BA"; cluster.oracleProviders[WBTC ] = "0xcE111096Cd2260436EA475fA6C70A284692D1887"; cluster.oracleProviders[ARB ] = "0x0fc12120957A8603905C7e089c2CB010c694c889"; // define supply caps here. 0 means no supply can occur, type(uint256).max means no cap defined hence max amount cluster.supplyCaps[USDC ] = 100_000_000; cluster.supplyCaps[USDT0 ] = 100_000_000; - cluster.supplyCaps[WETH ] = 50_000; - cluster.supplyCaps[wstETH] = 30_000; - cluster.supplyCaps[weETH ] = 30_000; + cluster.supplyCaps[sUSDS ] = 10_000_000; + cluster.supplyCaps[sUSDC ] = 10_000_000; + cluster.supplyCaps[WETH ] = 37_500; + cluster.supplyCaps[wstETH] = 22_500; + cluster.supplyCaps[weETH ] = 22_500; + cluster.supplyCaps[rsETH ] = 60; + cluster.supplyCaps[tETH ] = 100; + cluster.supplyCaps[ezETH ] = 375; cluster.supplyCaps[WBTC ] = 600; cluster.supplyCaps[ARB ] = 10_000_000; // define borrow caps here. 0 means no borrow can occur, type(uint256).max means no cap defined hence max amount cluster.borrowCaps[USDC ] = 90_000_000; cluster.borrowCaps[USDT0 ] = 90_000_000; - cluster.borrowCaps[WETH ] = 45_000; - cluster.borrowCaps[wstETH] = 15_000; - cluster.borrowCaps[weETH ] = 15_000; + cluster.borrowCaps[sUSDS ] = 8_000_000; + cluster.borrowCaps[sUSDC ] = 8_000_000; + cluster.borrowCaps[WETH ] = 33_000; + cluster.borrowCaps[wstETH] = 11_000; + cluster.borrowCaps[weETH ] = 11_000; + cluster.borrowCaps[rsETH ] = 30; + cluster.borrowCaps[tETH ] = 50; + cluster.borrowCaps[ezETH ] = 180; cluster.borrowCaps[WBTC ] = 540; cluster.borrowCaps[ARB ] = 8_000_000; @@ -95,17 +115,25 @@ contract Cluster is ManageCluster { // Base=0% APY, Kink(50%)=1.00% APY Max=40.00% APY uint256[4] memory irmETH_LST = [uint256(0), uint256(146829246), uint256(4818228676), uint256(2147483648)]; - // Base=0% APY, Kink(90%)=6.00% APY Max=40.00% APY - uint256[4] memory irmUSD = [uint256(0), uint256(477682641), uint256(20526145828), uint256(3865470566)]; + // Base=0% APY, Kink(90%)=6.50% APY Max=40.00% APY + uint256[4] memory irmUSD_1 = [uint256(0), uint256(516261061), uint256(20178940043), uint256(3865470566)]; + + // Base=0% APY, Kink(80%)=2.00% APY Max=40.00% APY + uint256[4] memory irmUSD_2 = [uint256(0), uint256(182632435), uint256(11682115056), uint256(3435973836)]; // Base=0% APY, Kink(80%)=5.00% APY Max=80.00% APY uint256[4] memory irmDEFI = [uint256(0), uint256(449973958), uint256(19883875652), uint256(3435973836)]; - cluster.kinkIRMParams[USDC ] = irmUSD; - cluster.kinkIRMParams[USDT0 ] = irmUSD; + cluster.kinkIRMParams[USDC ] = irmUSD_1; + cluster.kinkIRMParams[USDT0 ] = irmUSD_1; + cluster.kinkIRMParams[sUSDS ] = irmUSD_2; + cluster.kinkIRMParams[sUSDC ] = irmUSD_2; cluster.kinkIRMParams[WETH ] = irmETH; cluster.kinkIRMParams[wstETH] = irmETH_LST; cluster.kinkIRMParams[weETH ] = irmETH_LST; + cluster.kinkIRMParams[rsETH ] = irmETH_LST; + cluster.kinkIRMParams[tETH ] = irmETH_LST; + cluster.kinkIRMParams[ezETH ] = irmETH_LST; cluster.kinkIRMParams[WBTC ] = irmBTC; cluster.kinkIRMParams[ARB ] = irmDEFI; } @@ -118,15 +146,20 @@ contract Cluster is ManageCluster { // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ - // 0 1 2 3 4 5 6 - // USDC USDT0 WETH wstETH weETH WBTC ARB - /* 0 USDC */ [uint16(0.00e4), 0.96e4, 0.86e4, 0.84e4, 0.84e4, 0.86e4, 0.65e4], - /* 1 USDT0 */ [uint16(0.96e4), 0.00e4, 0.86e4, 0.84e4, 0.84e4, 0.86e4, 0.65e4], - /* 2 WETH */ [uint16(0.86e4), 0.86e4, 0.00e4, 0.95e4, 0.94e4, 0.86e4, 0.65e4], - /* 3 wstETH */ [uint16(0.84e4), 0.84e4, 0.95e4, 0.00e4, 0.93e4, 0.84e4, 0.65e4], - /* 4 weETH */ [uint16(0.83e4), 0.83e4, 0.94e4, 0.93e4, 0.00e4, 0.83e4, 0.65e4], - /* 5 WBTC */ [uint16(0.86e4), 0.86e4, 0.86e4, 0.84e4, 0.84e4, 0.00e4, 0.65e4], - /* 6 ARB */ [uint16(0.65e4), 0.65e4, 0.65e4, 0.65e4, 0.65e4, 0.65e4, 0.00e4] + // 0 1 2 3 4 5 6 7 8 9 10 11 + // USDC USDT0 sUSDS sUSDC WETH wstETH weETH rsETH tETH ezETH WBTC ARB + /* 0 USDC */ [uint16(0.00e4), 0.96e4, 0.96e4, 0.96e4, 0.86e4, 0.840e4, 0.84e4, 0.00e4, 0.000e4, 0.00e4, 0.86e4, 0.65e4], + /* 1 USDT0 */ [uint16(0.96e4), 0.00e4, 0.94e4, 0.94e4, 0.86e4, 0.840e4, 0.84e4, 0.00e4, 0.000e4, 0.00e4, 0.86e4, 0.65e4], + /* 2 sUSDS */ [uint16(0.96e4), 0.94e4, 0.00e4, 0.94e4, 0.84e4, 0.820e4, 0.81e4, 0.00e4, 0.000e4, 0.00e4, 0.84e4, 0.65e4], + /* 3 sUSDC */ [uint16(0.96e4), 0.94e4, 0.94e4, 0.00e4, 0.84e4, 0.820e4, 0.81e4, 0.00e4, 0.000e4, 0.00e4, 0.84e4, 0.65e4], + /* 4 WETH */ [uint16(0.86e4), 0.86e4, 0.84e4, 0.84e4, 0.00e4, 0.950e4, 0.94e4, 0.93e4, 0.930e4, 0.93e4, 0.86e4, 0.65e4], + /* 5 wstETH */ [uint16(0.84e4), 0.84e4, 0.82e4, 0.82e4, 0.95e4, 0.000e4, 0.93e4, 0.92e4, 0.925e4, 0.92e4, 0.84e4, 0.65e4], + /* 6 weETH */ [uint16(0.83e4), 0.83e4, 0.81e4, 0.81e4, 0.94e4, 0.930e4, 0.00e4, 0.91e4, 0.910e4, 0.91e4, 0.83e4, 0.65e4], + /* 7 rsETH */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.93e4, 0.920e4, 0.91e4, 0.00e4, 0.910e4, 0.91e4, 0.00e4, 0.00e4], + /* 8 tETH */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.93e4, 0.925e4, 0.91e4, 0.91e4, 0.000e4, 0.91e4, 0.00e4, 0.00e4], + /* 9 ezETH */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.93e4, 0.920e4, 0.91e4, 0.91e4, 0.910e4, 0.00e4, 0.00e4, 0.00e4], + /* 10 WBTC */ [uint16(0.86e4), 0.86e4, 0.84e4, 0.84e4, 0.86e4, 0.840e4, 0.84e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.65e4], + /* 11 ARB */ [uint16(0.65e4), 0.65e4, 0.65e4, 0.65e4, 0.65e4, 0.650e4, 0.65e4, 0.00e4, 0.000e4, 0.00e4, 0.65e4, 0.00e4] ]; // define external ltvs here. columns are liability vaults, rows are collateral vaults. diff --git a/script/production/arbitrum/clusters/ManageCluster.s.sol b/script/production/arbitrum/clusters/ManageCluster.s.sol index 068c5a37..06bf6914 100644 --- a/script/production/arbitrum/clusters/ManageCluster.s.sol +++ b/script/production/arbitrum/clusters/ManageCluster.s.sol @@ -10,8 +10,13 @@ abstract contract Addresses { address internal constant WETH = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1; address internal constant USDC = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831; address internal constant USDT0 = 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9; + address internal constant sUSDS = 0xdDb46999F8891663a8F2828d25298f70416d7610; + address internal constant sUSDC = 0x940098b108fB7D0a7E374f6eDED7760787464609; address internal constant wstETH = 0x5979D7b546E38E414F7E9822514be443A4800529; address internal constant weETH = 0x35751007a407ca6FEFfE80b3cB397736D2cf4dbe; + address internal constant rsETH = 0x4186BFC76E2E237523CBC30FD220FE055156b41F; + address internal constant tETH = 0xd09ACb80C1E8f2291862c4978A008791c9167003; + address internal constant ezETH = 0x2416092f143378750bb29b79eD961ab195CcEea5; address internal constant WBTC = 0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f; address internal constant ARB = 0x912CE59144191C1204E64559FE8253a0e49E6548; } diff --git a/script/production/arbitrum/governedPerspectiveVaults/GovernedPerspectiveVaults.csv b/script/production/arbitrum/governedPerspectiveVaults/GovernedPerspectiveVaults.csv index 823958c8..0669f16d 100644 --- a/script/production/arbitrum/governedPerspectiveVaults/GovernedPerspectiveVaults.csv +++ b/script/production/arbitrum/governedPerspectiveVaults/GovernedPerspectiveVaults.csv @@ -5,4 +5,14 @@ Vault,Governor,Whitelist 0xA8616E4D9f3f0aa01aff1d7c3b66249f8a5f1A58,Euler Arbitrum,Yes 0x5A8294CE02908B1da68c6c39695c9b0FbaF7675d,Euler Arbitrum,Yes 0x889E1c458B2469b70aCcdfb5B59726dC1668896C,Euler Arbitrum,Yes -0x7eD866D2D66c3149FaFE854C30C68a8BA7ceE8B9,Euler Arbitrum,Yes \ No newline at end of file +0x7eD866D2D66c3149FaFE854C30C68a8BA7ceE8B9,Euler Arbitrum,Yes +0x0EE8D628411F446BFbbe08BDeF53E42414C8fBC4,Euler Arbitrum,Yes +0xa7a9B773f139010f284E825a74060648d91dE37a,Euler Arbitrum,Yes +0xE96e07C16661744836a742Ef2090F11e84a86f4F,Euler Arbitrum,Yes +0xDBD974Eb5360d053ea0c56B4DaCF4A9D3E894Ee2,Euler Arbitrum,Yes +0xaA525D3142A5BDD3E55E8e983D3789b88F2FEB8f,Euler Arbitrum,Yes +0x6aFB8d3F6D4A34e9cB2f217317f4dc8e05Aa673b,K3 USDai,Yes +0x482C3E2530FAc8FE2c63AE007AD2695C6d685E98,K3 USDai,Yes +0x7D9790403FA53eF3E3a3389c259D244BDc61B785,K3 USDai,Yes +0xAABb9cbAC15a3D646dCdc6574bCFCfB989E1fDd8,K3 USDai,Yes +0x683B777A393BA94F3c903fba2b14A6b6fF80dbE7,K3 USDai,Yes \ No newline at end of file diff --git a/script/production/avalanche/governedPerspectiveVaults/GovernedPerspectiveVaults.csv b/script/production/avalanche/governedPerspectiveVaults/GovernedPerspectiveVaults.csv index dbe7c763..1729ae18 100644 --- a/script/production/avalanche/governedPerspectiveVaults/GovernedPerspectiveVaults.csv +++ b/script/production/avalanche/governedPerspectiveVaults/GovernedPerspectiveVaults.csv @@ -22,6 +22,7 @@ Vault,Governor,Whitelist 0x69B07dB605d0A08fbE9245c1466880AA36c8E1A7,Mev Capital,Yes 0x152179bfc75f780bFe5b0d3c0D3c797108fB24C3,Mev Capital,Yes 0x91bFd7192990c2A56dF4AceFf5Fe063B75b636A5,Mev Capital,Yes +0xa4284e26Ae6469aeE8eC38Aa9Db96fc62d6315A1,Mev Capital,Yes 0x6fC9b3a52944A577cd8971Fd8fDE0819001bC595,K3 Capital,Yes 0xa446938b0204Aa4055cdFEd68Ddf0E0d1BAB3E9E,K3 Capital,Yes 0x5030183B3DD0105d69D7d45595C120Fc4b542EC3,K3 Capital,Yes @@ -34,4 +35,8 @@ Vault,Governor,Whitelist 0xb9CC370a8f19322FC4BF69Da80c6C39FF8F2dB90,K3 Capital,Yes 0x902714C7661697c873C76dEC426b63B2593ecc0a,K3 Capital,Yes 0x76DE251BeE4A3B902857f6A0fCe8a320C4167E40,K3 Capital,Yes -0x51b47B3013863c52CA28D603De3C2d7a5FEf50B9,K3 Capital,Yes \ No newline at end of file +0x51b47B3013863c52CA28D603De3C2d7a5FEf50B9,K3 Capital,Yes +0x8f23Da78e3F31Ab5DEb75dC3282198bed630ffde,Keyring,Yes +0xea534105c2ccC0582D82B285aA47A6B446383d44,Keyring,Yes +0x04293b180bf9C57eD0923C99c784Cb571f0A9Ae9,Reservoir Labs,Yes +0xA321a38b03a7218157668a724E186f3a81CF56c8,Reservoir Labs,Yes \ No newline at end of file diff --git a/script/production/base/clusters/BaseCluster.json b/script/production/base/clusters/BaseCluster.json index d1e87022..e79c44ca 100644 --- a/script/production/base/clusters/BaseCluster.json +++ b/script/production/base/clusters/BaseCluster.json @@ -8,12 +8,13 @@ "0xEc25c49217C9Ed5006DB2FbB383CB692D4d1E9e8", "0xEc25c49217C9Ed5006DB2FbB383CB692D4d1E9e8", "0xEc25c49217C9Ed5006DB2FbB383CB692D4d1E9e8", - "0x757d2Da9a0994996ceC5C54D5af16d83fB976dEe", - "0x757d2Da9a0994996ceC5C54D5af16d83fB976dEe", + "0xA45ACA351613AF93cEb9C5bd4BB93C3Ec28f8c83", + "0xA45ACA351613AF93cEb9C5bd4BB93C3Ec28f8c83", + "0xA45ACA351613AF93cEb9C5bd4BB93C3Ec28f8c83", "0x71F44753512C2611609609C252664fCD74BA8bEC", "0x855FD4F004dfeA1f2Ca35e0d6bb6e41F20714539", "0xF807BA2f78A1A8c6cdAaeb802c041202bcCA0a1e", - "0x757d2Da9a0994996ceC5C54D5af16d83fB976dEe", + "0xA45ACA351613AF93cEb9C5bd4BB93C3Ec28f8c83", "0x48ce0Be4bF79927F177b18D923b4B044d4752f20" ], "oracleRouters": [ @@ -30,6 +31,7 @@ "0x6E183458600e66047A0f4D356d9DAa480DA1CA59", "0x6E183458600e66047A0f4D356d9DAa480DA1CA59", "0x6E183458600e66047A0f4D356d9DAa480DA1CA59", + "0x6E183458600e66047A0f4D356d9DAa480DA1CA59", "0x6E183458600e66047A0f4D356d9DAa480DA1CA59" ], "stubOracle": "0x176b59faD000cd22c819EB1b85eE4dD1f61b9b89", @@ -42,6 +44,7 @@ "0x8b70a855B057cA85F38Ebb2a7399D9FE0BDC1046", "0x841C92bfF53c81cDdb8ad557096B30C93fddb394", "0x0A1a3b5f2041F33522C4efc754a7D096f880eE16", + "0x72c8B07E5aD9F2DcC3cA2c05927c31ddCf2Ffe9A", "0x9ECD9fbbdA32b81dee51AdAed28c5C5039c87117", "0x882018411Bc4A020A879CEE183441fC9fa5D7f8B", "0x3f0d3Fd87A42BDaa3dfCC13ADA42eA922e638a7A", diff --git a/script/production/base/clusters/BaseCluster.s.sol b/script/production/base/clusters/BaseCluster.s.sol index fb3cfdab..d43ee84e 100644 --- a/script/production/base/clusters/BaseCluster.s.sol +++ b/script/production/base/clusters/BaseCluster.s.sol @@ -23,6 +23,7 @@ contract Cluster is ManageCluster { RETH, wsuperOETHb, USDC, + USDT0, EURC, cbBTC, LBTC, @@ -75,46 +76,49 @@ contract Cluster is ManageCluster { cluster.oracleProviders[weETH ] = "CrossAdapter=ChainlinkOracle+ChainlinkOracle"; cluster.oracleProviders[ezETH ] = "CrossAdapter=ChainlinkOracle+ChainlinkOracle"; cluster.oracleProviders[RETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; - cluster.oracleProviders[wsuperOETHb] = "ExternalVault|0x5A3AD0dA327b48e295961487B4ee1B0F6646e25D"; // Fixed Oracle + cluster.oracleProviders[wsuperOETHb] = "ExternalVault|0x5A3AD0dA327b48e295961487B4ee1B0F6646e25D"; cluster.oracleProviders[USDC ] = "ChainlinkOracle"; + cluster.oracleProviders[USDT0 ] = "0x94dae37fdf8302c5800661a93de43b77d8709925"; cluster.oracleProviders[EURC ] = "ChainlinkOracle"; - cluster.oracleProviders[cbBTC ] = "ChainlinkOracle"; + cluster.oracleProviders[cbBTC ] = "0xedcD625e06c487A68b5d9f2a5b020E9BE00b95A7"; cluster.oracleProviders[LBTC ] = "CrossAdapter=RedstoneClassicOracle+ChainlinkOracle"; cluster.oracleProviders[AERO ] = "ChainlinkOracle"; cluster.oracleProviders[USDS ] = "0x847BD1550634c35Ea5d6528B0414e0BE69584010"; cluster.oracleProviders[SUSDS ] = "0xdbcC3537800134A316f8D01eDa38d07c8d34174c"; // define supply caps here. 0 means no supply can occur, type(uint256).max means no cap defined hence max amount - cluster.supplyCaps[WETH ] = 15_000; - cluster.supplyCaps[wstETH] = 5_000; - cluster.supplyCaps[cbETH ] = 5_000; - cluster.supplyCaps[weETH ] = 5_000; - cluster.supplyCaps[ezETH ] = 5_000; - cluster.supplyCaps[RETH ] = 5_000; - cluster.supplyCaps[wsuperOETHb] = 2_500; + cluster.supplyCaps[WETH ] = 11_300; + cluster.supplyCaps[wstETH] = 950; + cluster.supplyCaps[cbETH ] = 450; + cluster.supplyCaps[weETH ] = 3_750; + cluster.supplyCaps[ezETH ] = 1_000; + cluster.supplyCaps[RETH ] = 1_000; + cluster.supplyCaps[wsuperOETHb] = 900; cluster.supplyCaps[USDC ] = 60_000_000; + cluster.supplyCaps[USDT0 ] = 6_000_000; cluster.supplyCaps[EURC ] = 20_000_000; - cluster.supplyCaps[cbBTC ] = 250; - cluster.supplyCaps[LBTC ] = 250; - cluster.supplyCaps[AERO ] = 2_000_000; - cluster.supplyCaps[USDS ] = 40_000_000; - cluster.supplyCaps[SUSDS ] = 20_000_000; + cluster.supplyCaps[cbBTC ] = 125; + cluster.supplyCaps[LBTC ] = 50; + cluster.supplyCaps[AERO ] = 500_000; + cluster.supplyCaps[USDS ] = 10_000_000; + cluster.supplyCaps[SUSDS ] = 5_000_000; // define borrow caps here. 0 means no borrow can occur, type(uint256).max means no cap defined hence max amount - cluster.borrowCaps[WETH ] = 12_700; - cluster.borrowCaps[wstETH] = 2_000; - cluster.borrowCaps[cbETH ] = 2_000; - cluster.borrowCaps[weETH ] = 1_250; - cluster.borrowCaps[ezETH ] = 1_250; - cluster.borrowCaps[RETH ] = 2_000; - cluster.borrowCaps[wsuperOETHb] = 625; + cluster.borrowCaps[WETH ] = 9_530; + cluster.borrowCaps[wstETH] = 400; + cluster.borrowCaps[cbETH ] = 400; + cluster.borrowCaps[weETH ] = 938; + cluster.borrowCaps[ezETH ] = 300; + cluster.borrowCaps[RETH ] = 400; + cluster.borrowCaps[wsuperOETHb] = 200; cluster.borrowCaps[USDC ] = 54_000_000; + cluster.borrowCaps[USDT0 ] = 5_400_000; cluster.borrowCaps[EURC ] = 18_000_000; - cluster.borrowCaps[cbBTC ] = 213; - cluster.borrowCaps[LBTC ] = 63; - cluster.borrowCaps[AERO ] = 1_600_000; - cluster.borrowCaps[USDS ] = 36_000_000; - cluster.borrowCaps[SUSDS ] = 18_000_000; + cluster.borrowCaps[cbBTC ] = 110; + cluster.borrowCaps[LBTC ] = 15; + cluster.borrowCaps[AERO ] = 400_000; + cluster.borrowCaps[USDS ] = 9_000_000; + cluster.borrowCaps[SUSDS ] = 4_500_000; // define IRM classes here and assign them to the assets { @@ -133,8 +137,8 @@ contract Cluster is ManageCluster { // Base=0% APY, Kink(25%)=4.60% APY Max=848.77% APY uint256[4] memory irmETH_LRT = [uint256(0), uint256(1327273625), uint256(21691866441), uint256(1073741824)]; - // Base=0% APY, Kink(90%)=5.00% APY Max=80.00% APY - uint256[4] memory irmUSD = [uint256(0), uint256(399976852), uint256(39767751304), uint256(3865470566)]; + // Base=0% APY, Kink(90%)=6.50% APY Max=40.00% APY + uint256[4] memory irmUSD = [uint256(0), uint256(516261061), uint256(20178940043), uint256(3865470566)]; // Base=0% APY, Kink(25%)=2.50% APY Max=100.00% APY uint256[4] memory irmBTC_LRT = [uint256(0), uint256(728739169), uint256(6575907893), uint256(1073741824)]; @@ -153,6 +157,7 @@ contract Cluster is ManageCluster { cluster.kinkIRMParams[RETH ] = irmETH_LRT; cluster.kinkIRMParams[wsuperOETHb] = irmETH_LRT; cluster.kinkIRMParams[USDC ] = irmUSD; + cluster.kinkIRMParams[USDT0 ] = irmUSD; cluster.kinkIRMParams[EURC ] = irmUSD; cluster.kinkIRMParams[cbBTC ] = irmBTC; cluster.kinkIRMParams[LBTC ] = irmBTC_LRT; @@ -169,22 +174,23 @@ contract Cluster is ManageCluster { // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 - // WETH wstETH cbETH weETH ezETH RETH wsOETHb USDC EURC cbBTC LBTC AERO USDS SUSDS - /* 0 WETH */ [uint16(0.00e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.80e4, 0.87e4, 0.85e4, 0.78e4, 0.78e4, 0.78e4, 0.87e4, 0.00e4], - /* 1 wstETH */ [uint16(0.93e4), 0.00e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.80e4, 0.83e4, 0.83e4, 0.77e4, 0.77e4, 0.77e4, 0.83e4, 0.00e4], - /* 2 cbETH */ [uint16(0.93e4), 0.93e4, 0.00e4, 0.92e4, 0.93e4, 0.93e4, 0.80e4, 0.80e4, 0.80e4, 0.75e4, 0.75e4, 0.75e4, 0.80e4, 0.00e4], - /* 3 weETH */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.80e4, 0.80e4, 0.80e4, 0.75e4, 0.75e4, 0.75e4, 0.80e4, 0.00e4], - /* 4 ezETH */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.90e4, 0.80e4, 0.77e4, 0.77e4, 0.72e4, 0.72e4, 0.72e4, 0.77e4, 0.00e4], - /* 5 RETH */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.80e4, 0.77e4, 0.77e4, 0.72e4, 0.72e4, 0.72e4, 0.77e4, 0.00e4], - /* 6 wsOETHb */ [uint16(0.93e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 7 USDC */ [uint16(0.85e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.00e4, 0.90e4, 0.80e4, 0.80e4, 0.80e4, 0.95e4, 0.00e4], - /* 8 EURC */ [uint16(0.85e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.90e4, 0.00e4, 0.80e4, 0.80e4, 0.80e4, 0.90e4, 0.00e4], - /* 9 cbBTC */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.00e4, 0.80e4, 0.80e4, 0.00e4, 0.90e4, 0.70e4, 0.80e4, 0.00e4], - /* 10 LBTC */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.00e4, 0.80e4, 0.80e4, 0.90e4, 0.00e4, 0.70e4, 0.80e4, 0.00e4], - /* 11 AERO */ [uint16(0.65e4), 0.65e4, 0.65e4, 0.65e4, 0.65e4, 0.65e4, 0.00e4, 0.65e4, 0.65e4, 0.65e4, 0.65e4, 0.00e4, 0.65e4, 0.00e4], - /* 12 USDS */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.00e4, 0.94e4, 0.92e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.00e4], - /* 13 SUSDS */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.94e4, 0.92e4, 0.00e4, 0.00e4, 0.00e4, 0.94e4, 0.00e4] + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + // WETH wstETH cbETH weETH ezETH RETH wsOETHb USDC USDT0 EURC cbBTC LBTC AERO USDS SUSDS + /* 0 WETH */ [uint16(0.00e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.80e4, 0.87e4, 0.85e4, 0.85e4, 0.78e4, 0.78e4, 0.78e4, 0.87e4, 0.00e4], + /* 1 wstETH */ [uint16(0.93e4), 0.00e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.80e4, 0.83e4, 0.81e4, 0.83e4, 0.77e4, 0.77e4, 0.77e4, 0.83e4, 0.00e4], + /* 2 cbETH */ [uint16(0.93e4), 0.93e4, 0.00e4, 0.92e4, 0.93e4, 0.93e4, 0.80e4, 0.80e4, 0.78e4, 0.80e4, 0.75e4, 0.75e4, 0.75e4, 0.80e4, 0.00e4], + /* 3 weETH */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.80e4, 0.80e4, 0.78e4, 0.80e4, 0.75e4, 0.75e4, 0.75e4, 0.80e4, 0.00e4], + /* 4 ezETH */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.90e4, 0.80e4, 0.77e4, 0.75e4, 0.77e4, 0.72e4, 0.72e4, 0.72e4, 0.77e4, 0.00e4], + /* 5 RETH */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.80e4, 0.77e4, 0.75e4, 0.77e4, 0.72e4, 0.72e4, 0.72e4, 0.77e4, 0.00e4], + /* 6 wsOETHb */ [uint16(0.93e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 7 USDC */ [uint16(0.85e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.00e4, 0.93e4, 0.90e4, 0.80e4, 0.80e4, 0.80e4, 0.95e4, 0.00e4], + /* 8 USDT0 */ [uint16(0.83e4), 0.81e4, 0.78e4, 0.78e4, 0.78e4, 0.78e4, 0.00e4, 0.94e4, 0.00e4, 0.88e4, 0.78e4, 0.78e4, 0.78e4, 0.93e4, 0.00e4], + /* 9 EURC */ [uint16(0.85e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.90e4, 0.88e4, 0.00e4, 0.80e4, 0.80e4, 0.80e4, 0.90e4, 0.00e4], + /* 10 cbBTC */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.00e4, 0.80e4, 0.78e4, 0.80e4, 0.00e4, 0.90e4, 0.70e4, 0.80e4, 0.00e4], + /* 11 LBTC */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.00e4, 0.80e4, 0.78e4, 0.80e4, 0.90e4, 0.00e4, 0.70e4, 0.80e4, 0.00e4], + /* 12 AERO */ [uint16(0.65e4), 0.65e4, 0.65e4, 0.65e4, 0.65e4, 0.65e4, 0.00e4, 0.65e4, 0.63e4, 0.65e4, 0.65e4, 0.65e4, 0.00e4, 0.65e4, 0.00e4], + /* 13 USDS */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.00e4, 0.94e4, 0.92e4, 0.92e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.00e4], + /* 14 SUSDS */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.94e4, 0.92e4, 0.92e4, 0.00e4, 0.00e4, 0.00e4, 0.94e4, 0.00e4] ]; // define external ltvs here. columns are liability vaults, rows are collateral vaults. diff --git a/script/production/base/clusters/ManageCluster.s.sol b/script/production/base/clusters/ManageCluster.s.sol index 62d57012..3691bb5f 100644 --- a/script/production/base/clusters/ManageCluster.s.sol +++ b/script/production/base/clusters/ManageCluster.s.sol @@ -15,6 +15,7 @@ abstract contract Addresses { address internal constant RETH = 0xB6fe221Fe9EeF5aBa221c348bA20A1Bf5e73624c; address internal constant wsuperOETHb = 0x7FcD174E80f264448ebeE8c88a7C4476AAF58Ea6; address internal constant USDC = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913; + address internal constant USDT0 = 0x102d758f688a4C1C5a80b116bD945d4455460282; address internal constant USDS = 0x820C137fa70C8691f0e44Dc420a5e53c168921Dc; address internal constant SUSDS = 0x5875eEE11Cf8398102FdAd704C9E96607675467a; address internal constant EURC = 0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42; diff --git a/script/production/base/governedPerspectiveVaults/GovernedPerspectiveVaults.csv b/script/production/base/governedPerspectiveVaults/GovernedPerspectiveVaults.csv index 29ad342f..02ba731a 100644 --- a/script/production/base/governedPerspectiveVaults/GovernedPerspectiveVaults.csv +++ b/script/production/base/governedPerspectiveVaults/GovernedPerspectiveVaults.csv @@ -13,6 +13,7 @@ Vault,Governor,Whitelist 0x556d518FDFDCC4027A3A1388699c5E11AC201D8b,Euler Base,Yes 0x65cFEF3Efbc5586f0c05299343b8BeFb3fF5d81a,Euler Base,Yes 0x841C92bfF53c81cDdb8ad557096B30C93fddb394,Euler Base,Yes +0x72c8B07E5aD9F2DcC3cA2c05927c31ddCf2Ffe9A,Euler Base,Yes 0xe72eA97aAF905c5f10040f78887cc8dE8eAec7E4,Euler Frontier yoBTC,Yes 0xFab9aF50F7A1Cfe201CAE1c15fCFdDaE7705ccD3,Euler Frontier yoBTC,Yes 0x774C08F8e78C47046d325C0331788954C35DF10a,Euler Frontier yoETH,Yes @@ -27,3 +28,5 @@ Vault,Governor,Whitelist 0x34ABB4501419b1E5f836567C58300c861164101A,Apostro Resolv,Yes 0xEdCc195Ca09c9FCC1DD30b152C0b82045Ff2F91f,Apostro Resolv,Yes 0x596dBb33131fa2991cf5651cB57e4b15682C7F93,Apostro Resolv,Yes +0xf4480166d66CFb9c5E12C843A8F844F512989289,Alterscope LRT,Yes +0xF3BB6b0a9bEAF9240D7F4a91341d5Df6bF37cAea,Alterscope LRT,Yes diff --git a/script/production/berachain/governedPerspectiveVaults/GovernedPerspectiveVaults.csv b/script/production/berachain/governedPerspectiveVaults/GovernedPerspectiveVaults.csv index 03cd8e74..9170dfc2 100644 --- a/script/production/berachain/governedPerspectiveVaults/GovernedPerspectiveVaults.csv +++ b/script/production/berachain/governedPerspectiveVaults/GovernedPerspectiveVaults.csv @@ -21,6 +21,7 @@ Vault,Governor,Whitelist 0x34018ac9DC4B114036Ca148Aa18C8f75594E5e95,Mev Capital,Yes 0x4eB3351066494852a03ffBBDE40a9776380Ce20D,Mev Capital,Yes 0xE3ecE76A7D1B07BcB0B5B6D38091E47C45994043,Mev Capital,Yes +0x8c0d62cEC0920f33c76cC99cfb703De060289D4A,Mev Capital,Yes 0x027DcAfB223f69d41Bd413C50854017718419585,Tulipa,Yes 0xE932da5A4d00536c224f8153f299cDcD8054c444,Tulipa,Yes 0x542B1ffd33C239C7AFc6511FB8855390Aa9c8aC2,Tulipa,Yes diff --git a/script/production/bsc/governedPerspectiveVaults/EulerEarnGovernedPerspectiveVaults.csv b/script/production/bsc/governedPerspectiveVaults/EulerEarnGovernedPerspectiveVaults.csv new file mode 100644 index 00000000..64fa4060 --- /dev/null +++ b/script/production/bsc/governedPerspectiveVaults/EulerEarnGovernedPerspectiveVaults.csv @@ -0,0 +1,2 @@ +Vault,Governor,Whitelist +0x27Ec22e4DcB70F7FfE1F6bb89e3284529492c05E,Euler USD1,Yes \ No newline at end of file diff --git a/script/production/frontier/EULSwap.json b/script/production/frontier/EULSwap.json index fadb6058..2159da86 100644 --- a/script/production/frontier/EULSwap.json +++ b/script/production/frontier/EULSwap.json @@ -3,7 +3,7 @@ "0x4CaF2f4847448b7103922fb9b926E80782dcDC6d" ], "irms": [ - "0x96e714c7963AF23c17878130C9FB5FEeB0751ca2" + "0x4568C213421fFd0cb308EEF4f41d8f0d943Fd5b2" ], "oracleRouters": [ "0x1FC53457F04fdd8C73B28934C0ee77f1a41F8BC7" diff --git a/script/production/frontier/EULSwap.s.sol b/script/production/frontier/EULSwap.s.sol index 29249395..eec4676f 100644 --- a/script/production/frontier/EULSwap.s.sol +++ b/script/production/frontier/EULSwap.s.sol @@ -22,8 +22,6 @@ contract Cluster is ManageCluster { function configureCluster() internal override { super.configureCluster(); - cluster.vaultsGovernor = getDeployer(); - // define unit of account here cluster.unitOfAccount = EUL; @@ -41,8 +39,8 @@ contract Cluster is ManageCluster { // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly { - // Base=0% APY Kink(90%)=5.0% APY Max=20.00% APY - cluster.kinkIRMParams[EUL] = [uint256(0), uint256(399976852), uint256(9852092153), uint256(3865470566)]; + // Base=0% APY Kink(95%)=6.0% APY Max=12.00% APY + cluster.kinkIRMParams[EUL] = [uint256(0), uint256(452541449), uint256(8124741138), uint256(4080218931)]; } // define ltv values here. columns are liability vaults, rows are collateral vaults diff --git a/script/production/frontier/Falcon.json b/script/production/frontier/Falcon.json index 865a3cbe..84f27d9a 100644 --- a/script/production/frontier/Falcon.json +++ b/script/production/frontier/Falcon.json @@ -1,12 +1,19 @@ { - "externalVaults": [], + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x2F9E82B49b542736216DA531EBAC2b6B32f43060", + "0x0000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000" ], "oracleRouters": [ + "0x1ada463F00833545b33A1B6551d0954Ba32be1fc", + "0x1ada463F00833545b33A1B6551d0954Ba32be1fc", "0x1ada463F00833545b33A1B6551d0954Ba32be1fc", "0x1ada463F00833545b33A1B6551d0954Ba32be1fc", "0x1ada463F00833545b33A1B6551d0954Ba32be1fc", @@ -15,8 +22,10 @@ "stubOracle": "0x0000000000000000000000000000000000000000", "vaults": [ "0x3573A84Bee11D49A1CbCe2b291538dE7a7dD81c6", + "0xbFdc482616787b420BC6C710212fE3167E7198e9", "0x412D0E31790D77b6e7a7872a9fd6967B6E640229", "0x2F849ba554C1ea2eDe9C240Bbe9d247dd6eC8A6B", - "0xE415952f5ee06f8A548F4f7D5bE18FBf144b4E4D" + "0xE415952f5ee06f8A548F4f7D5bE18FBf144b4E4D", + "0xa7A064f56FbcA60cBeD47eD3e13C4B945DEf7eC3" ] } \ No newline at end of file diff --git a/script/production/frontier/Falcon.sol b/script/production/frontier/Falcon.sol index a53ed4f5..ac31a29c 100644 --- a/script/production/frontier/Falcon.sol +++ b/script/production/frontier/Falcon.sol @@ -8,6 +8,7 @@ contract Cluster is ManageCluster { address internal constant USDf = 0xFa2B947eEc368f42195f24F36d2aF29f7c24CeC2; address internal constant sUSDf = 0xc8CF6D7991f15525488b2A83Df53468D682Ba4B0; address internal constant PT_sUSDf_25SEPT2025 = 0xAB365C0879024481E4ad3b47bd6FeA9c10014FbC; + address internal constant PT_USDf_29JAN2026 = 0xeC3b5e45dD278d5AB9CDB31754B54DB314e9D52a; function defineCluster() internal override { // define the path to the cluster addresses file here @@ -18,7 +19,7 @@ contract Cluster is ManageCluster { // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as // needed. // note however, that mappings may need reworking as they always use asset address as key. - cluster.assets = [USDC, USDf, sUSDf, PT_sUSDf_25SEPT2025]; + cluster.assets = [USDC, USDT, USDf, sUSDf, PT_sUSDf_25SEPT2025, PT_USDf_29JAN2026]; } function configureCluster() internal override { @@ -38,9 +39,11 @@ contract Cluster is ManageCluster { // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form // of a string. cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; cluster.oracleProviders[USDf ] = "0xEd8e9151602E40233D358d6C323d9F9717a1bec4"; cluster.oracleProviders[sUSDf ] = "ExternalVault|0xEd8e9151602E40233D358d6C323d9F9717a1bec4"; cluster.oracleProviders[PT_sUSDf_25SEPT2025 ] = "0x21414e20FBEf2c2212f2C658Aa42657EeA1b16ba"; + cluster.oracleProviders[PT_USDf_29JAN2026 ] = "0x82214dece7cda7ee19a4d627e3f134a5f2401fc1"; // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly { @@ -48,18 +51,29 @@ contract Cluster is ManageCluster { //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; cluster.irms[USDf ] = IRM_ADAPTIVE_USD; cluster.irms[sUSDf ] = IRM_ADAPTIVE_USD_YB; } // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ - // 0 1 2 3 - // USDC USDf sUSDf PT_sUSDf - /* 0 USDC */ [LTV_ZERO, LTV__LOW, LTV_ZERO, LTV_ZERO], - /* 1 USDf */ [LTV__LOW, LTV_ZERO, LTV_ZERO, LTV_ZERO], - /* 2 sUSDf */ [LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO], - /* 3 PT_sUSDf*/ [LTV__LOW, LTV_HIGH, LTV_HIGH, LTV_ZERO] + // 0 1 2 3 4 5 + // USDC USDT USDf sUSDf PT_sUSDf PT_USDf + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV__LOW, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV__LOW, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 2 USDf */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 3 sUSDf */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 4 PT_sUSDf*/ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 5 PT_USDf */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 4 5 + // USDC USDT USDf sUSDf PT_sUSDf PT_USDf + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO] ]; } } diff --git a/script/production/frontier/Hyperwave.json b/script/production/frontier/Hyperwave.json new file mode 100644 index 00000000..8c450a45 --- /dev/null +++ b/script/production/frontier/Hyperwave.json @@ -0,0 +1,25 @@ +{ + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], + "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x2F9E82B49b542736216DA531EBAC2b6B32f43060", + "0x0000000000000000000000000000000000000000" + ], + "oracleRouters": [ + "0x360204d8e924eB04045Af63b3Ed36c1DB6Bd333D", + "0x360204d8e924eB04045Af63b3Ed36c1DB6Bd333D", + "0x360204d8e924eB04045Af63b3Ed36c1DB6Bd333D", + "0x360204d8e924eB04045Af63b3Ed36c1DB6Bd333D" + ], + "stubOracle": "0x0000000000000000000000000000000000000000", + "vaults": [ + "0x3C75C170671acb394804DfAf63e4F9891C121625", + "0x22cC732cbca457F6811295bCE75B01822544bA52", + "0x4f36Bebf5dDb4b804F9C72644aEe82BAd165BFfc", + "0x9c6bDF412723ADF2798B163638083783506B26e3" + ] +} \ No newline at end of file diff --git a/script/production/frontier/Hyperwave.sol b/script/production/frontier/Hyperwave.sol new file mode 100644 index 00000000..e24067a9 --- /dev/null +++ b/script/production/frontier/Hyperwave.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {ManageCluster} from "./ManageCluster.s.sol"; + +contract Cluster is ManageCluster { + address internal constant hwHLP = 0x9FD7466f987Fd4C45a5BBDe22ED8aba5BC8D72d1; + address internal constant PT_hwHLP = 0x904673592a3FEbB74a30a73161e8C05A200C8961; + + function defineCluster() internal override { + // define the path to the cluster addresses file here + cluster.clusterAddressesPath = "/script/production/frontier/Hyperwave.json"; + + // do not change the order of the assets in the .assets array. if done, it must be reflected in other the other + // arrays the ltvs matrix. + // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as + // needed. + // note however, that mappings may need reworking as they always use asset address as key. + cluster.assets = [USDC, USDT, hwHLP, PT_hwHLP]; + } + + function configureCluster() internal override { + super.configureCluster(); + + // define unit of account here + cluster.unitOfAccount = USD; + + // define oracle providers here. + // adapter names can be found in the relevant adapter contract (as returned by the `name` function). + // for cross adapters, use the following format: "CrossAdapter=+". + // although Redstone Classic oracles reuse the ChainlinkOracle contract and returns "ChainlinkOracle" name, + // they should be referred to as "RedstoneClassicOracle". + // in case the asset is an ERC4626 vault itself (i.e. sUSDS) and is recognized as a valid external vault as per + // External Vaults Registry, the string should be preceeded by "ExternalVault|" prefix. this is in order to + // resolve the asset (vault) in the oracle router. + // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form + // of a string. + cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; + cluster.oracleProviders[hwHLP ] = "0x2b04C8067D55203235baC0Db823b970e2d7e48B0"; + cluster.oracleProviders[PT_hwHLP ] = "0xF9dE4293f3a11D657AC403a8985FC2f5dD156cE6"; + + // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly + { + // Base=0% APY Kink(90%)=2.7% APY Max=40.00% APY + //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; + + cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; + cluster.irms[hwHLP ] = IRM_ADAPTIVE_USD_YB; + } + + // define ltv values here. columns are liability vaults, rows are collateral vaults + cluster.ltvs = [ + // 0 1 2 3 + // USDC USDT hwHLP PT_hwHLP + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV__LOW, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV__LOW, LTV_ZERO], + /* 2 hwHLP */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO], + /* 5 PT_hwHLP*/ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 + // USDC USDT hwHLP PT_hwHLP + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO] + ]; + } +} diff --git a/script/production/frontier/Level.json b/script/production/frontier/Level.json index dd4a7704..2123fa16 100644 --- a/script/production/frontier/Level.json +++ b/script/production/frontier/Level.json @@ -1,6 +1,10 @@ { - "externalVaults": [], + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x2F9E82B49b542736216DA531EBAC2b6B32f43060", @@ -12,11 +16,13 @@ "0x0E9A05ab6C72880a67084D2d1A728c2eDd42aA34", "0x0E9A05ab6C72880a67084D2d1A728c2eDd42aA34", "0x0E9A05ab6C72880a67084D2d1A728c2eDd42aA34", + "0x0E9A05ab6C72880a67084D2d1A728c2eDd42aA34", "0x0E9A05ab6C72880a67084D2d1A728c2eDd42aA34" ], "stubOracle": "0x0000000000000000000000000000000000000000", "vaults": [ "0xF4Bc4239eDca81ed0d305701CB18A5Fd82cd06Ca", + "0x3bFA6657982A9Ada1388CF798F3f211711Daf4E5", "0xfc6f3A2Badb53973F69449Da690Cfef84dc4a359", "0x1e0b68A83Ef062CDE687351C472cFd0E9300A06d", "0xF2ec2d8fE1351bAFF31643855C0f4D1E63Bd1ce4", diff --git a/script/production/frontier/Level.s.sol b/script/production/frontier/Level.s.sol index 7bc62d27..41e71a7e 100644 --- a/script/production/frontier/Level.s.sol +++ b/script/production/frontier/Level.s.sol @@ -19,7 +19,7 @@ contract Cluster is ManageCluster { // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as // needed. // note however, that mappings may need reworking as they always use asset address as key. - cluster.assets = [USDC, lvlUSD, slvlUSD, PT_lvlUSD, PT_slvlUSD]; + cluster.assets = [USDC, USDT, lvlUSD, slvlUSD, PT_lvlUSD, PT_slvlUSD]; } function configureCluster() internal override { @@ -39,6 +39,7 @@ contract Cluster is ManageCluster { // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form // of a string. cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; cluster.oracleProviders[lvlUSD ] = "0x35402e99763fc9ed16f4d559ea7d87a18ac2127b"; cluster.oracleProviders[slvlUSD ] = "ExternalVault|0x35402e99763fc9ed16f4d559ea7d87a18ac2127b"; cluster.oracleProviders[PT_lvlUSD ] = "0xc6be2c0025e372322879dc5c57c34c671918ae6e"; @@ -50,19 +51,29 @@ contract Cluster is ManageCluster { //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; cluster.irms[lvlUSD ] = IRM_ADAPTIVE_USD; cluster.irms[slvlUSD] = IRM_ADAPTIVE_USD_YB; } // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ - // 0 1 2 3 4 - // USDC lvlUSD slvlUSD PT_lvlUSD PT_slvlUSD - /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], - /* 1 lvlUSD */ [LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], - /* 2 slvlUSD */ [LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], - /* 3 PT_lvlUSD */ [LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], - /* 4 PT_slvlUSD*/ [LTV__LOW, LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO] + // 0 1 2 3 4 5 + // USDC USDT lvlUSD slvlUSD PT_lvlUSD PT_slvlUSD + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 2 lvlUSD */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 3 slvlUSD */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 4 PT_lvlUSD */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 5 PT_slvlUSD*/ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 4 5 + // USDC USDT lvlUSD slvlUSD PT_lvlUSD PT_slvlUSD + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO] ]; } } diff --git a/script/production/frontier/ManageCluster.s.sol b/script/production/frontier/ManageCluster.s.sol index acc7cf95..83d7d47d 100644 --- a/script/production/frontier/ManageCluster.s.sol +++ b/script/production/frontier/ManageCluster.s.sol @@ -24,6 +24,11 @@ abstract contract Addresses { } else if (block.chainid == 8453) { WETH = 0x4200000000000000000000000000000000000006; USDC = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913; + USDT = 0x102d758f688a4C1C5a80b116bD945d4455460282; + } else if (block.chainid == 42161) { + WETH = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1; + USDC = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831; + USDT = 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9; } if (block.chainid == 1) { @@ -36,6 +41,11 @@ abstract contract Addresses { IRM_ADAPTIVE_USD_YB = 0x72C9D7c1e9e954c9Dc85E49dB76fF614a335d2a5; IRM_ADAPTIVE_ETH = 0xb70de5cEcA993c08BceE4296E3fEbcc9D7C0AdCD; IRM_ADAPTIVE_BTC = 0x26472E20e09a01AA50a0F2C4d96E99ac58268a8D; + } else if (block.chainid == 42161) { + IRM_ADAPTIVE_USD = 0x2D76638aA2fA9Ce16417485d46Ed8EEDC1Db1AA4; + IRM_ADAPTIVE_USD_YB = 0x0a473bbcBa1c89ffbD7AfACdD6CBE019Ab5F2dD4; + IRM_ADAPTIVE_ETH = 0xF583692cCa56b084cb1f9D4C3e3939C43f73409D; + IRM_ADAPTIVE_BTC = 0xE1f126e815D4BF8CCE2F94552196EcA9a7c1B96c; } } diff --git a/script/production/frontier/Pareto.json b/script/production/frontier/Pareto.json index c2957997..d24de218 100644 --- a/script/production/frontier/Pareto.json +++ b/script/production/frontier/Pareto.json @@ -1,16 +1,22 @@ { - "externalVaults": [], + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x0000000000000000000000000000000000000000" ], "oracleRouters": [ - "0x82b82F2e8cAa7432Bf8e13ee51c3a713bc2B4CE6", - "0x82b82F2e8cAa7432Bf8e13ee51c3a713bc2B4CE6" + "0x096781fF62a3eF19bdD577974547f52a824fAECd", + "0x096781fF62a3eF19bdD577974547f52a824fAECd", + "0x096781fF62a3eF19bdD577974547f52a824fAECd" ], "stubOracle": "0x0000000000000000000000000000000000000000", "vaults": [ - "0xFbd4F1d0B2AF661bD43ef6577966daa6587f0b7c", - "0x834b16f76A950bFCDB517A533709F81E58C5a83E" + "0xa94F9CE821C7bD57cc12991CB46ca19f5789278F", + "0xF2ef3e32FCF4BfE21266727281B73F95Cd520411", + "0xa3e0943d0196F76db58d3549C9a7528Ef4ac335F" ] } \ No newline at end of file diff --git a/script/production/frontier/Pareto.s.sol b/script/production/frontier/Pareto.s.sol index 08e56f62..7c620ca7 100644 --- a/script/production/frontier/Pareto.s.sol +++ b/script/production/frontier/Pareto.s.sol @@ -16,7 +16,7 @@ contract Cluster is ManageCluster { // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as // needed. // note however, that mappings may need reworking as they always use asset address as key. - cluster.assets = [USDC, sUSP]; + cluster.assets = [USDC, USDT, sUSP]; } function configureCluster() internal override { @@ -36,7 +36,8 @@ contract Cluster is ManageCluster { // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form // of a string. cluster.oracleProviders[USDC] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; - cluster.oracleProviders[sUSP] = "ExternalVault|0x8424db29b3f19a6B494d20cB3071669fd277Ed0C"; + cluster.oracleProviders[USDT] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; + cluster.oracleProviders[sUSP] = "ExternalVault|0x4cfa6e2783c02ce427d720e22e574c8c89c3b7c1"; // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly { @@ -44,14 +45,24 @@ contract Cluster is ManageCluster { //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; cluster.irms[USDC] = IRM_ADAPTIVE_USD; + cluster.irms[USDT] = IRM_ADAPTIVE_USD; } // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ - // 0 1 - // USDC sUSP - /* 0 USDC */ [LTV_ZERO, LTV_ZERO], - /* 1 sUSP */ [LTV_HIGH, LTV_ZERO] + // 0 1 2 + // USDC USDT sUSP + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 2 sUSP */ [LTV_HIGH, LTV_HIGH, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 + // USDC USDT sUSP + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO] ]; } } diff --git a/script/production/frontier/Renzo.json b/script/production/frontier/Renzo.json index 4c16ec9f..89e74ccb 100644 --- a/script/production/frontier/Renzo.json +++ b/script/production/frontier/Renzo.json @@ -1,5 +1,7 @@ { - "externalVaults": [], + "externalVaults": [ + "0xD8b27CF359b7D15710a5BE299AF6e7Bf904984C2" + ], "irms": [ "0xe7d9dC800b9373aB0Ac25ce81Fdc85De2176Bb50", "0x0000000000000000000000000000000000000000" diff --git a/script/production/frontier/Renzo.s.sol b/script/production/frontier/Renzo.s.sol index 973602da..c82e13aa 100644 --- a/script/production/frontier/Renzo.s.sol +++ b/script/production/frontier/Renzo.s.sol @@ -51,5 +51,12 @@ contract Cluster is ManageCluster { /* 0 WETH */ [LTV_ZERO, LTV_ZERO], /* 1 ezETH */ [LTV_HIGH, LTV_ZERO] ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 + // WETH ezETH + /* 0 Prime WETH */ [LTV_HIGH, LTV_ZERO] + ]; } } diff --git a/script/production/frontier/Reservoir.json b/script/production/frontier/Reservoir.json new file mode 100644 index 00000000..5dbe781f --- /dev/null +++ b/script/production/frontier/Reservoir.json @@ -0,0 +1,25 @@ +{ + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], + "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x2F9E82B49b542736216DA531EBAC2b6B32f43060" + ], + "oracleRouters": [ + "0xD567691c3BcBd5B46CB109cE8Ee7e2a1f2479434", + "0xD567691c3BcBd5B46CB109cE8Ee7e2a1f2479434", + "0xD567691c3BcBd5B46CB109cE8Ee7e2a1f2479434", + "0xD567691c3BcBd5B46CB109cE8Ee7e2a1f2479434" + ], + "stubOracle": "0x0000000000000000000000000000000000000000", + "vaults": [ + "0x15A60a5300c1D9179d4c0e2B49bac6146794Ae1F", + "0x607589437A3b52f536706642a9b7c70192C37940", + "0xACD489AdEC33cd7c46FC448cf77376f1EaF5f3ab", + "0xb5c0EC2b53b87720f2D99B75c01C6d4Da0e724F8" + ] +} \ No newline at end of file diff --git a/script/production/frontier/Reservoir.sol b/script/production/frontier/Reservoir.sol new file mode 100644 index 00000000..1e8dd686 --- /dev/null +++ b/script/production/frontier/Reservoir.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {ManageCluster} from "./ManageCluster.s.sol"; + +contract Cluster is ManageCluster { + address internal constant rUSD = 0x09D4214C03D01F49544C0448DBE3A27f768F2b34; + address internal constant srUSD = 0x738d1115B90efa71AE468F1287fc864775e23a31; + + function defineCluster() internal override { + // define the path to the cluster addresses file here + cluster.clusterAddressesPath = "/script/production/frontier/Reservoir.json"; + + // do not change the order of the assets in the .assets array. if done, it must be reflected in other the other + // arrays the ltvs matrix. + // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as + // needed. + // note however, that mappings may need reworking as they always use asset address as key. + cluster.assets = [USDC, USDT, rUSD, srUSD]; + } + + function configureCluster() internal override { + super.configureCluster(); + + cluster.oracleRoutersGovernor = cluster.vaultsGovernor = governorAddresses.accessControlEmergencyGovernor; + + // define unit of account here + cluster.unitOfAccount = USD; + + // define oracle providers here. + // adapter names can be found in the relevant adapter contract (as returned by the `name` function). + // for cross adapters, use the following format: "CrossAdapter=+". + // although Redstone Classic oracles reuse the ChainlinkOracle contract and returns "ChainlinkOracle" name, + // they should be referred to as "RedstoneClassicOracle". + // in case the asset is an ERC4626 vault itself (i.e. sUSDS) and is recognized as a valid external vault as per + // External Vaults Registry, the string should be preceeded by "ExternalVault|" prefix. this is in order to + // resolve the asset (vault) in the oracle router. + // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form + // of a string. + cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; + cluster.oracleProviders[rUSD ] = "0x01dbd40296c232c2c58c99ff69084b256bee33ee"; + cluster.oracleProviders[srUSD] = "0xd54bc197150487a40d4ebd4fb215ca4fa996173e"; + + // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly + { + // Base=0% APY Kink(90%)=2.7% APY Max=40.00% APY + //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; + + cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; + cluster.irms[rUSD ] = IRM_ADAPTIVE_USD; + cluster.irms[srUSD ] = IRM_ADAPTIVE_USD_YB; + } + + // define ltv values here. columns are liability vaults, rows are collateral vaults + cluster.ltvs = [ + // 0 1 2 3 + // USDC USDT rUSD srUSD + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV__LOW, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV__LOW, LTV_ZERO], + /* 2 rUSD */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO], + /* 3 srUSD */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 + // USDC USDT rUSD srUSD + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO] + ]; + } +} diff --git a/script/production/frontier/Spark.json b/script/production/frontier/Spark.json new file mode 100644 index 00000000..6c082026 --- /dev/null +++ b/script/production/frontier/Spark.json @@ -0,0 +1,25 @@ +{ + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], + "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x0000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000" + ], + "oracleRouters": [ + "0x7516DB548B7bBC551F7213F77A275af2EdA6555d", + "0x7516DB548B7bBC551F7213F77A275af2EdA6555d", + "0x7516DB548B7bBC551F7213F77A275af2EdA6555d", + "0x7516DB548B7bBC551F7213F77A275af2EdA6555d" + ], + "stubOracle": "0x0000000000000000000000000000000000000000", + "vaults": [ + "0x58CD6Ae0Bd452d3219366C7ddD37cA1A12d2ff59", + "0x7fD46A66b5Ed6dC395603678cf9BE8846e01Fe25", + "0x13a2322907cea4CE62525476f9dAc191f0B590Db", + "0x00011d9A1EB3d7278b8DF2391e2E32f6f9bcF293" + ] +} \ No newline at end of file diff --git a/script/production/frontier/Spark.sol b/script/production/frontier/Spark.sol new file mode 100644 index 00000000..45a794e5 --- /dev/null +++ b/script/production/frontier/Spark.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {ManageCluster} from "./ManageCluster.s.sol"; + +contract Cluster is ManageCluster { + address internal constant sUSDS = 0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD; + address internal constant PT_USDS_14AUG2025 = 0xFfEc096c087C13Cc268497B89A613cACE4DF9A48; + + function defineCluster() internal override { + // define the path to the cluster addresses file here + cluster.clusterAddressesPath = "/script/production/frontier/Spark.json"; + + // do not change the order of the assets in the .assets array. if done, it must be reflected in other the other + // arrays the ltvs matrix. + // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as + // needed. + // note however, that mappings may need reworking as they always use asset address as key. + cluster.assets = [USDC, USDT, sUSDS, PT_USDS_14AUG2025]; + } + + function configureCluster() internal override { + super.configureCluster(); + + cluster.oracleRoutersGovernor = cluster.vaultsGovernor = governorAddresses.accessControlEmergencyGovernor; + + // define unit of account here + cluster.unitOfAccount = USD; + + // define oracle providers here. + // adapter names can be found in the relevant adapter contract (as returned by the `name` function). + // for cross adapters, use the following format: "CrossAdapter=+". + // although Redstone Classic oracles reuse the ChainlinkOracle contract and returns "ChainlinkOracle" name, + // they should be referred to as "RedstoneClassicOracle". + // in case the asset is an ERC4626 vault itself (i.e. sUSDS) and is recognized as a valid external vault as per + // External Vaults Registry, the string should be preceeded by "ExternalVault|" prefix. this is in order to + // resolve the asset (vault) in the oracle router. + // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form + // of a string. + cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; + cluster.oracleProviders[sUSDS] = "ExternalVault|0xF58F4d2Cd0ee43624dc442e726871B115DBDd9f0"; + cluster.oracleProviders[PT_USDS_14AUG2025] = "0x5B12cE5FDaFb14399e0fFe6a5410fBEC63f6B066"; + + // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly + { + // Base=0% APY Kink(90%)=2.7% APY Max=40.00% APY + //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; + + cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; + } + + // define ltv values here. columns are liability vaults, rows are collateral vaults + cluster.ltvs = [ + // 0 1 2 3 + // USDC USDT sUSDS PT_USDS + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 2 sUSDS */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO], + /* 3 PT_USDS */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 + // USDC USDT sUSDS PT_USDS + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO] + ]; + } +} diff --git a/script/production/frontier/Strata.json b/script/production/frontier/Strata.json new file mode 100644 index 00000000..9a202eca --- /dev/null +++ b/script/production/frontier/Strata.json @@ -0,0 +1,28 @@ +{ + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], + "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x2F9E82B49b542736216DA531EBAC2b6B32f43060", + "0x0000000000000000000000000000000000000000" + ], + "oracleRouters": [ + "0x848C9230DC53025eDB37032e4eb95e238c7E4b07", + "0x848C9230DC53025eDB37032e4eb95e238c7E4b07", + "0x848C9230DC53025eDB37032e4eb95e238c7E4b07", + "0x848C9230DC53025eDB37032e4eb95e238c7E4b07", + "0x848C9230DC53025eDB37032e4eb95e238c7E4b07" + ], + "stubOracle": "0x0000000000000000000000000000000000000000", + "vaults": [ + "0x53AfE3343f322c4189Ab69E0D048efd154259419", + "0x09FcE883cC16894274802c01e3b9cD90EAE4e43d", + "0x6331D36C27D967c4261D59a8f80d58d03089810A", + "0xBd360BB80E6CBe86e533B672Df6BFc054602ADBD", + "0xCfC6a55Aa72DCF3755A515aE8B82552028b63D2A" + ] +} \ No newline at end of file diff --git a/script/production/frontier/Strata.sol b/script/production/frontier/Strata.sol new file mode 100644 index 00000000..09d55440 --- /dev/null +++ b/script/production/frontier/Strata.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {ManageCluster} from "./ManageCluster.s.sol"; + +contract Cluster is ManageCluster { + address internal constant USDe = 0x4c9EDD5852cd905f086C759E8383e09bff1E68B3; + address internal constant pUSDe = 0xA62B204099277762d1669d283732dCc1B3AA96CE; + address internal constant PT_pUSDe = 0xF3f491e5608f8B8a6Fd9E9d66a4a4036d7FD282C; + + function defineCluster() internal override { + // define the path to the cluster addresses file here + cluster.clusterAddressesPath = "/script/production/frontier/Strata.json"; + + // do not change the order of the assets in the .assets array. if done, it must be reflected in other the other + // arrays the ltvs matrix. + // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as + // needed. + // note however, that mappings may need reworking as they always use asset address as key. + cluster.assets = [USDC, USDT, USDe, pUSDe, PT_pUSDe]; + } + + function configureCluster() internal override { + super.configureCluster(); + + // define unit of account here + cluster.unitOfAccount = USD; + + // define oracle providers here. + // adapter names can be found in the relevant adapter contract (as returned by the `name` function). + // for cross adapters, use the following format: "CrossAdapter=+". + // although Redstone Classic oracles reuse the ChainlinkOracle contract and returns "ChainlinkOracle" name, + // they should be referred to as "RedstoneClassicOracle". + // in case the asset is an ERC4626 vault itself (i.e. sUSDS) and is recognized as a valid external vault as per + // External Vaults Registry, the string should be preceeded by "ExternalVault|" prefix. this is in order to + // resolve the asset (vault) in the oracle router. + // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form + // of a string. + cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; + cluster.oracleProviders[USDe ] = "0x95dF7A30aF54cc05d1CFB1E9d7655f12269b8439"; + cluster.oracleProviders[pUSDe ] = "ExternalVault|0x95dF7A30aF54cc05d1CFB1E9d7655f12269b8439"; + cluster.oracleProviders[PT_pUSDe] = "0xD7AD788Fee2a7f7CADA6e82860D8DAed9eF21895"; + + // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly + { + // Base=0% APY Kink(90%)=2.7% APY Max=40.00% APY + //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; + + cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; + cluster.irms[USDe ] = IRM_ADAPTIVE_USD; + cluster.irms[pUSDe ] = IRM_ADAPTIVE_USD_YB; + } + + // define ltv values here. columns are liability vaults, rows are collateral vaults + cluster.ltvs = [ + // 0 1 2 3 4 + // USDC USDT USDe pUSDe PT_pUSDe + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV__LOW, LTV_ZERO, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV__LOW, LTV_ZERO, LTV_ZERO], + /* 2 USDe */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 3 pUSDe */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 4 PT_pUSDe*/ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_HIGH, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 4 + // USDC USDT USDe pUSDe PT_pUSDe + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO] + ]; + } +} diff --git a/script/production/frontier/USDai.json b/script/production/frontier/USDai.json new file mode 100644 index 00000000..e3c8ed06 --- /dev/null +++ b/script/production/frontier/USDai.json @@ -0,0 +1,30 @@ +{ + "externalVaults": [ + "0x0a1eCC5Fe8C9be3C809844fcBe615B46A869b899", + "0x37512F45B4ba8808910632323b73783Ca938CD51", + "0x31D2db91CF6Fb085F1566b95aEaA441FeDcb2638", + "0x784B2bbB1AdeBF2a6C300e52DaFe7dDb9888d416" + ], + "irms": [ + "0xac610F80e26E2D162f5EB01c0ae4F782e62cFF30", + "0xac610F80e26E2D162f5EB01c0ae4F782e62cFF30", + "0x0000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000", + "0xac610F80e26E2D162f5EB01c0ae4F782e62cFF30" + ], + "oracleRouters": [ + "0xE4e35ab751E9e06a67eC08E321b3353C3a328157", + "0xE4e35ab751E9e06a67eC08E321b3353C3a328157", + "0xE4e35ab751E9e06a67eC08E321b3353C3a328157", + "0xE4e35ab751E9e06a67eC08E321b3353C3a328157", + "0xE4e35ab751E9e06a67eC08E321b3353C3a328157" + ], + "stubOracle": "0x0000000000000000000000000000000000000000", + "vaults": [ + "0x6aFB8d3F6D4A34e9cB2f217317f4dc8e05Aa673b", + "0x482C3E2530FAc8FE2c63AE007AD2695C6d685E98", + "0x7D9790403FA53eF3E3a3389c259D244BDc61B785", + "0xAABb9cbAC15a3D646dCdc6574bCFCfB989E1fDd8", + "0x683B777A393BA94F3c903fba2b14A6b6fF80dbE7" + ] +} \ No newline at end of file diff --git a/script/production/frontier/USDai.sol b/script/production/frontier/USDai.sol new file mode 100644 index 00000000..5d630472 --- /dev/null +++ b/script/production/frontier/USDai.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {ManageCluster} from "./ManageCluster.s.sol"; + +contract Cluster is ManageCluster { + address internal constant USDai = 0x0A1a1A107E45b7Ced86833863f482BC5f4ed82EF; + address internal constant sUSDai = 0x0B2b2B2076d95dda7817e785989fE353fe955ef9; + address internal constant USDe = 0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34; + + function defineCluster() internal override { + // define the path to the cluster addresses file here + cluster.clusterAddressesPath = "/script/production/frontier/USDai.json"; + + // do not change the order of the assets in the .assets array. if done, it must be reflected in other the other + // arrays the ltvs matrix. + // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as + // needed. + // note however, that mappings may need reworking as they always use asset address as key. + cluster.assets = [USDC, USDT, USDai, sUSDai, USDe]; + } + + function configureCluster() internal override { + super.configureCluster(); + + cluster.oracleRoutersGovernor = cluster.vaultsGovernor = 0x060DB084bF41872861f175d83f3cb1B5566dfEA3; + + // define unit of account here + cluster.unitOfAccount = USD; + + // define oracle providers here. + // adapter names can be found in the relevant adapter contract (as returned by the `name` function). + // for cross adapters, use the following format: "CrossAdapter=+". + // although Redstone Classic oracles reuse the ChainlinkOracle contract and returns "ChainlinkOracle" name, + // they should be referred to as "RedstoneClassicOracle". + // in case the asset is an ERC4626 vault itself (i.e. sUSDS) and is recognized as a valid external vault as per + // External Vaults Registry, the string should be preceeded by "ExternalVault|" prefix. this is in order to + // resolve the asset (vault) in the oracle router. + // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form + // of a string. + cluster.oracleProviders[USDC ] = "0xEeB17ddb1B604c22d878e2b2a90B2Bf4E7d36641"; + cluster.oracleProviders[USDT ] = "0x3b24485168B448ED1da471265c3Bc4fBAaC4a2ab"; + cluster.oracleProviders[USDai ] = "0xae80AadE8Ff7cc7fE8493338898073fB1A4FB057"; + cluster.oracleProviders[sUSDai] = "ExternalVault|0xae80AadE8Ff7cc7fE8493338898073fB1A4FB057"; + cluster.oracleProviders[USDe ] = "0xD76802F99c339D3085C59027dDD9D4AE4957a651"; + + // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly + { + // Base=0% APY Kink(90%)=7.5% APY Max=70.00% APY + uint256[4] memory irm = [uint256(0), uint256(592877497), uint256(19489392122), uint256(3865470566)]; + + cluster.kinkIRMParams[USDC] = irm; + cluster.kinkIRMParams[USDT] = irm; + cluster.kinkIRMParams[USDe] = irm; + } + + cluster.supplyCaps[USDC ] = 50_000_000; + cluster.supplyCaps[USDT ] = 50_000_000; + cluster.supplyCaps[USDai ] = 50_000_000; + cluster.supplyCaps[sUSDai] = 50_000_000; + cluster.supplyCaps[USDe ] = 50_000_000; + + // define ltv values here. columns are liability vaults, rows are collateral vaults + cluster.ltvs = [ + // 0 1 2 3 4 + // USDC USDT USDai sUSDai USDe + /* 0 USDC */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 USDT */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 2 USDai */ [0.940e4, 0.905e4, LTV_ZERO, LTV_ZERO, 0.905e4 ], + /* 3 sUSDai */ [0.850e4, 0.800e4, LTV_ZERO, LTV_ZERO, 0.800e4 ], + /* 4 USDe */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO] + ]; + + cluster.borrowLTVsOverride = [ + // 0 1 2 3 4 + // USDC USDT USDai sUSDai USDe + /* 0 USDC */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 USDT */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 2 USDai */ [0.915e4, 0.880e4, LTV_ZERO, LTV_ZERO, 0.880e4 ], + /* 3 sUSDai */ [0.800e4, 0.750e4, LTV_ZERO, LTV_ZERO, 0.750e4 ], + /* 4 USDe */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 4 + // USDC USDT USDai sUSDai USDe + /* 0 Euler USDC */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 Euler USDT */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 2 Escrow USDAi */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 3 Escrow USDe */ [LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO] + ]; + } +} diff --git a/script/production/frontier/Yala.json b/script/production/frontier/Yala.json index 0052834c..5ff96a51 100644 --- a/script/production/frontier/Yala.json +++ b/script/production/frontier/Yala.json @@ -1,11 +1,16 @@ { - "externalVaults": [], + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x0000000000000000000000000000000000000000" ], "oracleRouters": [ + "0xb7Ccc55B02514C0E2ECf797a499487EdD34D2009", "0xb7Ccc55B02514C0E2ECf797a499487EdD34D2009", "0xb7Ccc55B02514C0E2ECf797a499487EdD34D2009", "0xb7Ccc55B02514C0E2ECf797a499487EdD34D2009" @@ -13,6 +18,7 @@ "stubOracle": "0x0000000000000000000000000000000000000000", "vaults": [ "0x481D4909D7ca2eb27c4975f08dCE07DBeF0d3Fa7", + "0x2dF9753E62f46B299F59E632bd18EdfE4970922e", "0x1F46186AF85A967416b17380800c69860B7C516F", "0x0F93f35c0664A6a8231ccAe7E22f652c9c075b32" ] diff --git a/script/production/frontier/Yala.sol b/script/production/frontier/Yala.sol index 263fc924..f1413f9f 100644 --- a/script/production/frontier/Yala.sol +++ b/script/production/frontier/Yala.sol @@ -17,7 +17,7 @@ contract Cluster is ManageCluster { // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as // needed. // note however, that mappings may need reworking as they always use asset address as key. - cluster.assets = [USDC, YU, PT_YU_04SEP2025]; + cluster.assets = [USDC, USDT, YU, PT_YU_04SEP2025]; } function configureCluster() internal override { @@ -37,6 +37,7 @@ contract Cluster is ManageCluster { // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form // of a string. cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; cluster.oracleProviders[YU ] = "0xFc9A5a244935CE0d62F1C1aFE8EFf0299cF604B6"; cluster.oracleProviders[PT_YU_04SEP2025 ] = "0x0bE8Db7a0e2867A64a7f15de28cb178C28aa0387"; @@ -46,16 +47,26 @@ contract Cluster is ManageCluster { //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; cluster.irms[YU ] = IRM_ADAPTIVE_USD; } // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ - // 0 1 2 - // USDC YU PT_YU_04SEP2025 - /* 0 USDC */ [LTV_ZERO, LTV__LOW, LTV_ZERO], - /* 1 YU */ [LTV__LOW, LTV_ZERO, LTV_ZERO], - /* 2 PT_YU_04SEP2025 */ [LTV__LOW, LTV_HIGH, LTV_ZERO] + // 0 1 2 3 + // USDC USDT YU PT_YU_04SEP2025 + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV__LOW, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV__LOW, LTV_ZERO], + /* 2 YU */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO], + /* 3 PT_YU_04SEP2025 */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 + // USDC USDT YU PT_YU_04SEP2025 + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO] ]; } } diff --git a/script/production/frontier/YieldFi.json b/script/production/frontier/YieldFi.json new file mode 100644 index 00000000..0046272b --- /dev/null +++ b/script/production/frontier/YieldFi.json @@ -0,0 +1,25 @@ +{ + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], + "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", + "0x2F9E82B49b542736216DA531EBAC2b6B32f43060", + "0x0000000000000000000000000000000000000000" + ], + "oracleRouters": [ + "0x34D515A26176432723622E690F13042C39c00D2B", + "0x34D515A26176432723622E690F13042C39c00D2B", + "0x34D515A26176432723622E690F13042C39c00D2B", + "0x34D515A26176432723622E690F13042C39c00D2B" + ], + "stubOracle": "0x0000000000000000000000000000000000000000", + "vaults": [ + "0xc727069c0eb261Be642272fe3848518192683fFc", + "0xd90f695D98b6E1fAA7BA516A777fF12cc3C111a4", + "0x3eD8f77Ca6FD9e5c6DBBcC9696BF93F30C3A2BA5", + "0xb76e9E04d4356756c9b8E002Cc4dabFA4e02BD93" + ] +} \ No newline at end of file diff --git a/script/production/frontier/YieldFi.s.sol b/script/production/frontier/YieldFi.s.sol new file mode 100644 index 00000000..871ce854 --- /dev/null +++ b/script/production/frontier/YieldFi.s.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {ManageCluster} from "./ManageCluster.s.sol"; + +contract Cluster is ManageCluster { + address internal constant yUSD = 0x19Ebd191f7A24ECE672ba13A302212b5eF7F35cb; + address internal constant PT_yUSD = 0xD1d0fF7BB555f57A9604CE06bca704ab97A0049A; + + function defineCluster() internal override { + // define the path to the cluster addresses file here + cluster.clusterAddressesPath = "/script/production/frontier/YieldFi.json"; + + // do not change the order of the assets in the .assets array. if done, it must be reflected in other the other + // arrays the ltvs matrix. + // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as + // needed. + // note however, that mappings may need reworking as they always use asset address as key. + cluster.assets = [USDC, USDT, yUSD, PT_yUSD]; + } + + function configureCluster() internal override { + super.configureCluster(); + + // define unit of account here + cluster.unitOfAccount = USD; + + // define oracle providers here. + // adapter names can be found in the relevant adapter contract (as returned by the `name` function). + // for cross adapters, use the following format: "CrossAdapter=+". + // although Redstone Classic oracles reuse the ChainlinkOracle contract and returns "ChainlinkOracle" name, + // they should be referred to as "RedstoneClassicOracle". + // in case the asset is an ERC4626 vault itself (i.e. sUSDS) and is recognized as a valid external vault as per + // External Vaults Registry, the string should be preceeded by "ExternalVault|" prefix. this is in order to + // resolve the asset (vault) in the oracle router. + // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form + // of a string. + cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; + cluster.oracleProviders[yUSD ] = "ExternalVault|0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[PT_yUSD ] = "0x5Bc6C01611dC945eA2F05d9e5d670846bD3a554C"; + + // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly + { + // Base=0% APY Kink(90%)=2.7% APY Max=40.00% APY + //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; + + cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; + cluster.irms[yUSD ] = IRM_ADAPTIVE_USD_YB; + } + + // define ltv values here. columns are liability vaults, rows are collateral vaults + cluster.ltvs = [ + // 0 1 2 3 + // USDC USDT yUSD PT_yUSD + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 2 yUSD */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 3 PT_yUSD */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 + // USDC USDT yUSD PT_yUSD + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO] + ]; + } +} diff --git a/script/production/frontier/hgETH.json b/script/production/frontier/hgETH.json index cdb13ce5..2f477f95 100644 --- a/script/production/frontier/hgETH.json +++ b/script/production/frontier/hgETH.json @@ -1,5 +1,7 @@ { - "externalVaults": [], + "externalVaults": [ + "0xD8b27CF359b7D15710a5BE299AF6e7Bf904984C2" + ], "irms": [ "0xF1a82e49c565511DF5aA36eF2b23ba9e4aF0985B", "0xF1a82e49c565511DF5aA36eF2b23ba9e4aF0985B", diff --git a/script/production/frontier/hgETH.sol b/script/production/frontier/hgETH.sol index e074f562..4f46e312 100644 --- a/script/production/frontier/hgETH.sol +++ b/script/production/frontier/hgETH.sol @@ -56,5 +56,12 @@ contract Cluster is ManageCluster { /* 1 hgETH */ [LTV__LOW, LTV_ZERO, LTV_ZERO], /* 2 PT_hgETH_26JUN2026*/ [LTV__LOW, LTV_HIGH, LTV_ZERO] ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 + // WETH hgETH PT_hgETH_26JUN2026 + /* 0 Prime WETH */ [LTV_HIGH, LTV_ZERO, LTV_ZERO] + ]; } } diff --git a/script/production/frontier/mEDGE.json b/script/production/frontier/mEDGE.json index 99b6c0a1..6ccf41b4 100644 --- a/script/production/frontier/mEDGE.json +++ b/script/production/frontier/mEDGE.json @@ -1,11 +1,18 @@ { - "externalVaults": [], + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x2F9E82B49b542736216DA531EBAC2b6B32f43060", + "0x0000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000" ], "oracleRouters": [ + "0xa0f15bAD3ad2561A23F0887b88737d8B23DE64Df", + "0xa0f15bAD3ad2561A23F0887b88737d8B23DE64Df", "0xa0f15bAD3ad2561A23F0887b88737d8B23DE64Df", "0xa0f15bAD3ad2561A23F0887b88737d8B23DE64Df", "0xa0f15bAD3ad2561A23F0887b88737d8B23DE64Df" @@ -13,7 +20,9 @@ "stubOracle": "0x0000000000000000000000000000000000000000", "vaults": [ "0x09136DAC538B54994170a6905507a74562A80ed3", + "0x122e9eA082D8c060Bb1a3476aa18B9E739fBbAAf", "0xD53f83c7CA5189007C09b5D867a8116bC0540724", - "0x94EdbB8F7543593FF1B8D2871eC4730B59c97888" + "0x94EdbB8F7543593FF1B8D2871eC4730B59c97888", + "0x561fF99A243868fdf755705b1B83e6C4E8B8B0dF" ] } \ No newline at end of file diff --git a/script/production/frontier/mEDGE.s.sol b/script/production/frontier/mEDGE.s.sol index 7f537402..5ae0d4a0 100644 --- a/script/production/frontier/mEDGE.s.sol +++ b/script/production/frontier/mEDGE.s.sol @@ -7,6 +7,7 @@ import {ManageCluster} from "./ManageCluster.s.sol"; contract Cluster is ManageCluster { address internal constant mEDGE = 0xbB51E2a15A9158EBE2b0Ceb8678511e063AB7a55; address internal constant PT_mEDGE = 0x7f01d0FCe9BC646389483384C41B4d71c7139f11; + address internal constant PT_mEDGE_new = 0x2E3229674085F5490a4cC2558ab96aEDC3ab25D1; function defineCluster() internal override { // define the path to the cluster addresses file here @@ -17,7 +18,7 @@ contract Cluster is ManageCluster { // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as // needed. // note however, that mappings may need reworking as they always use asset address as key. - cluster.assets = [USDC, mEDGE, PT_mEDGE]; + cluster.assets = [USDC, USDT, mEDGE, PT_mEDGE, PT_mEDGE_new]; } function configureCluster() internal override { @@ -37,8 +38,10 @@ contract Cluster is ManageCluster { // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form // of a string. cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; cluster.oracleProviders[mEDGE ] = "0xc8228b83f1d97a431a48bd9bc3e971c8b418d889"; cluster.oracleProviders[PT_mEDGE] = "0xe8192efbf40faa247f1c4fb792d986057fc69a15"; + cluster.oracleProviders[PT_mEDGE_new] = "0x78978df843d230b7e038241b9ebe2df2adf27f35"; // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly { @@ -46,16 +49,27 @@ contract Cluster is ManageCluster { //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; cluster.irms[mEDGE] = IRM_ADAPTIVE_USD_YB; } // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ - // 0 1 2 - // USDC mEDGE PT_mEDGE - /* 0 USDC */ [LTV_ZERO, LTV_ZERO, LTV_ZERO], - /* 1 mEDGE */ [LTV__LOW, LTV_ZERO, LTV_ZERO], - /* 2 PT_mEDGE*/ [LTV__LOW, LTV_HIGH, LTV_ZERO] + // 0 1 2 3 4 + // USDC USDT mEDGE PT_mEDGE PT_mEDGE + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 2 mEDGE */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 3 PT_mEDGE*/ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 4 PT_mEDGE*/ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 4 + // USDC USDT mEDGE PT_mEDGE PT_mEDGE + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO] ]; } } diff --git a/script/production/frontier/mMEV.json b/script/production/frontier/mMEV.json index 65e4974e..b93683be 100644 --- a/script/production/frontier/mMEV.json +++ b/script/production/frontier/mMEV.json @@ -1,11 +1,18 @@ { - "externalVaults": [], + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x2F9E82B49b542736216DA531EBAC2b6B32f43060", + "0x0000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000" ], "oracleRouters": [ + "0x82A2B4D8EDE60a9ef4B7f529b424B9cC4CD7000B", + "0x82A2B4D8EDE60a9ef4B7f529b424B9cC4CD7000B", "0x82A2B4D8EDE60a9ef4B7f529b424B9cC4CD7000B", "0x82A2B4D8EDE60a9ef4B7f529b424B9cC4CD7000B", "0x82A2B4D8EDE60a9ef4B7f529b424B9cC4CD7000B" @@ -13,7 +20,9 @@ "stubOracle": "0x0000000000000000000000000000000000000000", "vaults": [ "0x98281466aBcF48eAAD8c6E22dEdD18A3426A93b4", + "0x75E695C60aF0780F8c9FA79e37946a02f4481c09", "0x3F7CcadEd39Fd9D06Eb0498ABEb7EAAB569E79Ad", - "0x819662Ab6Fe32B52100fa32aE3e0e8b36B4C5638" + "0x819662Ab6Fe32B52100fa32aE3e0e8b36B4C5638", + "0xdc685C0b34eDd19f702a8ad4cD4d8279F6452AC8" ] } \ No newline at end of file diff --git a/script/production/frontier/mMEV.s.sol b/script/production/frontier/mMEV.s.sol index 11d8831c..662dc532 100644 --- a/script/production/frontier/mMEV.s.sol +++ b/script/production/frontier/mMEV.s.sol @@ -7,6 +7,7 @@ import {ManageCluster} from "./ManageCluster.s.sol"; contract Cluster is ManageCluster { address internal constant mMEV = 0x030b69280892c888670EDCDCD8B69Fd8026A0BF3; address internal constant PT_mMEV = 0x1132065009850C72E27B7950C0f9285d1D103589; + address internal constant PT_mMEV_new = 0x61da65F0534C6A4F4c9757f2979A923c08d6D2aa; function defineCluster() internal override { // define the path to the cluster addresses file here @@ -17,7 +18,7 @@ contract Cluster is ManageCluster { // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as // needed. // note however, that mappings may need reworking as they always use asset address as key. - cluster.assets = [USDC, mMEV, PT_mMEV]; + cluster.assets = [USDC, USDT, mMEV, PT_mMEV, PT_mMEV_new]; } function configureCluster() internal override { @@ -37,8 +38,10 @@ contract Cluster is ManageCluster { // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form // of a string. cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; cluster.oracleProviders[mMEV ] = "0xf5c2dfd1740d18ad7cf23fba76cc11d877802937"; cluster.oracleProviders[PT_mMEV] = "0x8c6ba8c189fc9f88fc72533ea60b9c4134a650f0"; + cluster.oracleProviders[PT_mMEV_new] = "0x83910e00f7662146e01f61d555a0577187e9bc11"; // define IRM classes here and assign them to the assets or refer to the adaptive IRM address directly { @@ -46,16 +49,27 @@ contract Cluster is ManageCluster { //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; cluster.irms[USDC] = IRM_ADAPTIVE_USD; + cluster.irms[USDT] = IRM_ADAPTIVE_USD; cluster.irms[mMEV] = IRM_ADAPTIVE_USD_YB; } // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ - // 0 1 2 - // USDC mMEV PT_mMEV - /* 0 USDC */ [LTV_ZERO, LTV_ZERO, LTV_ZERO], - /* 1 mMEV */ [LTV__LOW, LTV_ZERO, LTV_ZERO], - /* 2 PT_mMEV */ [LTV__LOW, LTV_HIGH, LTV_ZERO] + // 0 1 2 3 4 + // USDC USDT mMEV PT_mMEV PT_mMEV + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 2 mMEV */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 3 PT_mMEV */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 4 PT_mMEV */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 4 + // USDC USDT mMEV PT_mMEV PT_mMEV + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO, LTV_ZERO] ]; } } diff --git a/script/production/frontier/pufETH.json b/script/production/frontier/pufETH.json index 8a209424..4f1adaad 100644 --- a/script/production/frontier/pufETH.json +++ b/script/production/frontier/pufETH.json @@ -1,5 +1,7 @@ { - "externalVaults": [], + "externalVaults": [ + "0xD8b27CF359b7D15710a5BE299AF6e7Bf904984C2" + ], "irms": [ "0xF1a82e49c565511DF5aA36eF2b23ba9e4aF0985B", "0xF1a82e49c565511DF5aA36eF2b23ba9e4aF0985B" diff --git a/script/production/frontier/pufETH.sol b/script/production/frontier/pufETH.sol index d2519298..aeace279 100644 --- a/script/production/frontier/pufETH.sol +++ b/script/production/frontier/pufETH.sol @@ -51,5 +51,12 @@ contract Cluster is ManageCluster { /* 0 WETH */ [LTV_ZERO, LTV__LOW], /* 1 pufETH */ [LTV__LOW, LTV_ZERO] ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 + // WETH pufETH + /* 0 Prime WETH */ [LTV_HIGH, LTV_ZERO] + ]; } } diff --git a/script/production/frontier/sDOLA.json b/script/production/frontier/sDOLA.json index b0f9cc90..1dfa1059 100644 --- a/script/production/frontier/sDOLA.json +++ b/script/production/frontier/sDOLA.json @@ -1,11 +1,16 @@ { - "externalVaults": [], + "externalVaults": [ + "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", + "0x313603FA690301b0CaeEf8069c065862f9162162" + ], "irms": [ + "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x66d56E8Acad6a8fb6914753317cD3277D458E540", "0x0000000000000000000000000000000000000000" ], "oracleRouters": [ + "0x7Feb31a351db833f544141D2956eb105e4C4Fe6b", "0x7Feb31a351db833f544141D2956eb105e4C4Fe6b", "0x7Feb31a351db833f544141D2956eb105e4C4Fe6b", "0x7Feb31a351db833f544141D2956eb105e4C4Fe6b" @@ -13,6 +18,7 @@ "stubOracle": "0x0000000000000000000000000000000000000000", "vaults": [ "0x81f8ac1a4756BfE9D7ce138C0C3baD2Cb5E8a582", + "0x77710edfeDfB7e9186CBA71b258C75ea2AED5f84", "0xE668c3F45D126A72cf696Ff46054918Cf1337786", "0x3152EC91ec776f918Cc2090F58319A5a614536e0" ] diff --git a/script/production/frontier/sDOLA.sol b/script/production/frontier/sDOLA.sol index 51bee970..0df7ae70 100644 --- a/script/production/frontier/sDOLA.sol +++ b/script/production/frontier/sDOLA.sol @@ -17,7 +17,7 @@ contract Cluster is ManageCluster { // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as // needed. // note however, that mappings may need reworking as they always use asset address as key. - cluster.assets = [USDC, DOLA, sDOLA]; + cluster.assets = [USDC, USDT, DOLA, sDOLA]; } function configureCluster() internal override { @@ -37,6 +37,7 @@ contract Cluster is ManageCluster { // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form // of a string. cluster.oracleProviders[USDC ] = "0xD35657aE033A86FFa8fc6Bc767C5eb57C7c3D4B8"; + cluster.oracleProviders[USDT ] = "0x575Ffc02361368A2708c00bC7e299d1cD1c89f8A"; cluster.oracleProviders[DOLA ] = "0x6E91fBd747B6bEa1720b324c54Fb66a1619bcb36"; cluster.oracleProviders[sDOLA ] = "ExternalVault|0x6E91fBd747B6bEa1720b324c54Fb66a1619bcb36"; @@ -46,16 +47,26 @@ contract Cluster is ManageCluster { //cluster.kinkIRMParams[WETH] = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; cluster.irms[USDC ] = IRM_ADAPTIVE_USD; + cluster.irms[USDT ] = IRM_ADAPTIVE_USD; cluster.irms[DOLA ] = IRM_ADAPTIVE_USD; } // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ - // 0 1 2 - // USDC DOLA sDOLA - /* 0 USDC */ [LTV_ZERO, LTV__LOW, LTV_ZERO], - /* 1 DOLA */ [LTV__LOW, LTV_ZERO, LTV_ZERO], - /* 2 sDOLA */ [LTV__LOW, LTV_HIGH, LTV_ZERO] + // 0 1 2 3 + // USDC USDT DOLA sDOLA + /* 0 USDC */ [LTV_ZERO, LTV_HIGH, LTV__LOW, LTV_ZERO], + /* 1 USDT */ [LTV_HIGH, LTV_ZERO, LTV__LOW, LTV_ZERO], + /* 2 DOLA */ [LTV__LOW, LTV__LOW, LTV_ZERO, LTV_ZERO], + /* 3 sDOLA */ [LTV__LOW, LTV__LOW, LTV_HIGH, LTV_ZERO] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + cluster.externalLTVs = [ + // 0 1 2 3 + // USDC USDT DOLA sDOLA + /* 0 Prime USDC */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO], + /* 1 Prime USDT */ [LTV_HIGH, LTV_HIGH, LTV_ZERO, LTV_ZERO] ]; } } diff --git a/script/production/linea/clusters/LineaCluster.json b/script/production/linea/clusters/LineaCluster.json new file mode 100644 index 00000000..2e83b18d --- /dev/null +++ b/script/production/linea/clusters/LineaCluster.json @@ -0,0 +1,34 @@ +{ + "externalVaults": [], + "irms": [ + "0x7eEd90B3957a804F8bCC184CF9DeA5ecaa1179Ad", + "0x4db123eAc5aa81AeF98b8513e0BDfA61487a3cC3", + "0x7eEd90B3957a804F8bCC184CF9DeA5ecaa1179Ad", + "0x4db123eAc5aa81AeF98b8513e0BDfA61487a3cC3", + "0x7eEd90B3957a804F8bCC184CF9DeA5ecaa1179Ad", + "0x4db123eAc5aa81AeF98b8513e0BDfA61487a3cC3", + "0x7eEd90B3957a804F8bCC184CF9DeA5ecaa1179Ad", + "0x4db123eAc5aa81AeF98b8513e0BDfA61487a3cC3" + ], + "oracleRouters": [ + "0xeeb05f8BEB1ddf86225D50faF153e0F5C9Af3b1A", + "0xeeb05f8BEB1ddf86225D50faF153e0F5C9Af3b1A", + "0xeeb05f8BEB1ddf86225D50faF153e0F5C9Af3b1A", + "0xeeb05f8BEB1ddf86225D50faF153e0F5C9Af3b1A", + "0xeeb05f8BEB1ddf86225D50faF153e0F5C9Af3b1A", + "0xeeb05f8BEB1ddf86225D50faF153e0F5C9Af3b1A", + "0xfeaE75cE05158CB1Db71dbb58cA8C42416A5b4BF", + "0xfeaE75cE05158CB1Db71dbb58cA8C42416A5b4BF" + ], + "stubOracle": "0x0000000000000000000000000000000000000000", + "vaults": [ + "0xa8A02E6a894a490D04B6cd480857A19477854968", + "0x359e363c11fC619BE76EEC8BaAa01e61D521aA18", + "0xF4712fC5E6483DE9e1Ff661D95DD686664327086", + "0x8955d7dCdE9bD9694B64732aD28fF2113eb217B4", + "0x8bf8EdC911Ab3f0ea4a27c51Cb88b57ccE5356f1", + "0x873FEA936C29C8a9f3e0D7caCFC1Dc46E2A93e56", + "0x179DfD3eCDC6f5B8F8788584F3289D10c6F1afb8", + "0x5DF4080d8d1a85457d699E6a85255fc4087B8Abf" + ] +} \ No newline at end of file diff --git a/script/production/linea/clusters/LineaCluster.s.sol b/script/production/linea/clusters/LineaCluster.s.sol new file mode 100644 index 00000000..bedb3c8f --- /dev/null +++ b/script/production/linea/clusters/LineaCluster.s.sol @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; +import {ManageCluster} from "./ManageCluster.s.sol"; +import {OracleVerifier} from "../../../utils/SanityCheckOracle.s.sol"; + +contract Cluster is ManageCluster { + function defineCluster() internal override { + // define the path to the cluster addresses file here + cluster.clusterAddressesPath = "/script/production/linea/clusters/LineaCluster.json"; + + // do not change the order of the assets in the .assets array. if done, it must be reflected in other the other arrays the ltvs matrix. + // if more than one vauls has to be deployed for the same asset, it can be added in the array as many times as needed. + // note however, that mappings may need reworking as they always use asset address as key. + cluster.assets = [ + WETH, + wstETH, + WETH, + weETH, + WETH, + ezETH, + WETH, + wrsETH + ]; + } + + function configureCluster() internal override { + // define the governors here + cluster.oracleRoutersGovernor = cluster.vaultsGovernor = governorAddresses.accessControlEmergencyGovernor; + + // define unit of account here + cluster.unitOfAccount = WETH; + + // define fee receiver here and interest fee here. if needed to be defined per asset, populate the feeReceiverOverride and interestFeeOverride mappings + cluster.feeReceiver = address(0); + cluster.interestFee = 0.1e4; + + // define max liquidation discount here. if needed to be defined per asset, populate the maxLiquidationDiscountOverride mapping + cluster.maxLiquidationDiscount = 0.15e4; + + // define liquidation cool off time here. if needed to be defined per asset, populate the liquidationCoolOffTimeOverride mapping + cluster.liquidationCoolOffTime = 1; + + // define hook target and hooked ops here. if needed to be defined per asset, populate the hookTargetOverride and hookedOpsOverride mappings + cluster.hookTarget = address(0); + cluster.hookedOps = 0; + + // define config flags here. if needed to be defined per asset, populate the configFlagsOverride mapping + cluster.configFlags = 0; + + // define oracle providers here. + // adapter names can be found in the relevant adapter contract (as returned by the `name` function). + // for cross adapters, use the following format: "CrossAdapter=+". + // although Redstone Classic oracles reuse the ChainlinkOracle contract and returns "ChainlinkOracle" name, + // they should be referred to as "RedstoneClassicOracle". + // in case the asset is an ERC4626 vault itself (i.e. sUSDS) and is recognized as a valid external vault as per + // External Vaults Registry, the string should be preceeded by "ExternalVault|" prefix. this is in order to resolve + // the asset (vault) in the oracle router. + // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form of a string. + cluster.oracleProviders[wstETH] = "0x9d7BB1b8b82A7C2409aE9d1133700e4e7Ea34ffE"; + cluster.oracleProviders[weETH ] = "0x2A00BA96A1779a3bCfB728906b22D1145ABCD659"; + cluster.oracleProviders[ezETH ] = "0xBb91e02922ab31F17554BEFA65a581CE0EDE32eD"; + cluster.oracleProviders[wrsETH] = "0xB23fc49c0eA1BcD360c21EE1e31472e2b30D9524"; + + // define supply caps here. 0 means no supply can occur, type(uint256).max means no cap defined hence max amount + cluster.supplyCaps[WETH ] = 20_000; + cluster.supplyCaps[wstETH ] = 10_000; + cluster.supplyCaps[weETH ] = 5_000; + cluster.supplyCaps[ezETH ] = 5_000; + cluster.supplyCaps[wrsETH ] = 5_000; + + // define borrow caps here. 0 means no borrow can occur, type(uint256).max means no cap defined hence max amount + cluster.borrowCaps[WETH ] = type(uint256).max; + cluster.borrowCaps[wstETH ] = 5_000; + cluster.borrowCaps[weETH ] = 2_500; + cluster.borrowCaps[ezETH ] = 2_500; + cluster.borrowCaps[wrsETH ] = 2_500; + + // define IRM classes here and assign them to the assets + { + // Base=0% APY Kink(90%)=2.70% APY Max=8.00% APY + uint256[4] memory irmETH = [uint256(0), uint256(218407859), uint256(3712599046), uint256(3865470566)]; + + // Base=0% APY, Kink(50%)=2.00% APY Max=12.00% APY + uint256[4] memory irmETH_LST = [uint256(0), uint256(292211896), uint256(1380090972), uint256(2147483648)]; + + cluster.kinkIRMParams[WETH ] = irmETH; + cluster.kinkIRMParams[wstETH] = irmETH_LST; + cluster.kinkIRMParams[weETH ] = irmETH_LST; + cluster.kinkIRMParams[ezETH ] = irmETH_LST; + cluster.kinkIRMParams[wrsETH] = irmETH_LST; + } + + // define the ramp duration to be used, in case the liquidation LTVs have to be ramped down + cluster.rampDuration = 1 days; + + // define the spread between borrow and liquidation ltv + cluster.spreadLTV = 0.01e4; + + // define ltv values here. columns are liability vaults, rows are collateral vaults + cluster.ltvs = [ + // 0 1 2 3 4 5 6 7 + // WETH wstETH WETH weETH WETH ezETH WETH wrsETH + /* 0 WETH */ [uint16(0.00e4), 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 1 wstETH */ [uint16(0.95e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 2 WETH */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 3 weETH */ [uint16(0.00e4), 0.00e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 4 WETH */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.93e4, 0.00e4, 0.00e4], + /* 5 ezETH */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4], + /* 6 WETH */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.93e4], + /* 7 wrsETH */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.95e4, 0.00e4] + ]; + + // define external ltvs here. columns are liability vaults, rows are collateral vaults. + // double check the order of collaterals against the order of externalVaults in the addresses file + } + + function postOperations() internal view override { + for (uint256 i = 0; i < cluster.vaults.length; ++i) { + OracleVerifier.verifyOracleConfig(lensAddresses.oracleLens, cluster.vaults[i], false); + } + } +} diff --git a/script/production/linea/clusters/ManageCluster.s.sol b/script/production/linea/clusters/ManageCluster.s.sol new file mode 100644 index 00000000..424a11a0 --- /dev/null +++ b/script/production/linea/clusters/ManageCluster.s.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {ManageClusterBase} from "../../ManageClusterBase.s.sol"; + +abstract contract Addresses { + address internal constant USD = address(840); + address internal constant BTC = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB; + address internal constant WETH = 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f; + address internal constant wstETH = 0xB5beDd42000b71FddE22D3eE8a79Bd49A568fC8F; + address internal constant weETH = 0x1Bf74C010E6320bab11e2e5A532b5AC15e0b8aA6; + address internal constant ezETH = 0x2416092f143378750bb29b79eD961ab195CcEea5; + address internal constant wrsETH = 0xD2671165570f41BBB3B0097893300b6EB6101E6C; +} + +abstract contract ManageCluster is ManageClusterBase, Addresses {} diff --git a/script/production/linea/governedPerspectiveVaults/GovernedPerspectiveVaults.csv b/script/production/linea/governedPerspectiveVaults/GovernedPerspectiveVaults.csv new file mode 100644 index 00000000..fd8316a4 --- /dev/null +++ b/script/production/linea/governedPerspectiveVaults/GovernedPerspectiveVaults.csv @@ -0,0 +1,20 @@ +Vault,Governor,Whitelist +0xa8A02E6a894a490D04B6cd480857A19477854968,Euler Linea,Yes +0x359e363c11fC619BE76EEC8BaAa01e61D521aA18,Euler Linea,Yes +0xF4712fC5E6483DE9e1Ff661D95DD686664327086,Euler Linea,Yes +0x8955d7dCdE9bD9694B64732aD28fF2113eb217B4,Euler Linea,Yes +0x8bf8EdC911Ab3f0ea4a27c51Cb88b57ccE5356f1,Euler Linea,Yes +0x873FEA936C29C8a9f3e0D7caCFC1Dc46E2A93e56,Euler Linea,Yes +0x179DfD3eCDC6f5B8F8788584F3289D10c6F1afb8,Euler Linea,Yes +0x5DF4080d8d1a85457d699E6a85255fc4087B8Abf,Euler Linea,Yes +0x14EfcC1Ae56e2fF75204Ef2Fb0DE43378d0beaDA,Zerolend Linea,Yes +0x085f80Df643307e04f23281F6fdbfAA13865E852,Zerolend Linea,Yes +0x9aC2F0A564B7396A8692E1558d23a12d5a2aBb1F,Zerolend Linea,Yes +0xb135dcf653dafb5ddaa93f926d7000aa3222efee,Re7 WETH,Yes +0xb770dc4be757ad72bcb7b8ff4958fb5c6ee5aa49,Re7 WETH,Yes +0xb747b627c3b67cdc0aeaf78fd7174ae5e5bfa796,Re7 WETH,Yes +0x9947f3d2ae676be4612eb4d80e94f6441e47a2a9,Re7 WETH,Yes +0x92ba0ded54184ab00f7edd1bc5eba488cc8d9de0,Re7 WETH,Yes +0xfb6448b96637d90fcf2e4ad2c622a487d0496e6f,Re7 USD,Yes +0xcbef9be95738290188b25ca9a6dd2bec417a578c,Re7 USD,Yes +0xb11fd944cf5e8678b5db42305aff03b7942a3cab,Re7 USD,Yes \ No newline at end of file diff --git a/script/production/mainnet/clusters/ManageCluster.s.sol b/script/production/mainnet/clusters/ManageCluster.s.sol index 69edfe0a..2ae4fcda 100644 --- a/script/production/mainnet/clusters/ManageCluster.s.sol +++ b/script/production/mainnet/clusters/ManageCluster.s.sol @@ -27,6 +27,7 @@ abstract contract Addresses { address internal constant mTBILL = 0xDD629E5241CbC5919847783e6C96B2De4754e438; address internal constant USDe = 0x4c9EDD5852cd905f086C759E8383e09bff1E68B3; address internal constant eUSDe = 0x90D2af7d622ca3141efA4d8f1F24d86E5974Cc8F; + address internal constant pUSDe = 0xA62B204099277762d1669d283732dCc1B3AA96CE; address internal constant wUSDM = 0x57F5E098CaD7A3D1Eed53991D4d66C45C9AF7812; address internal constant EURC = 0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c; address internal constant sUSDe = 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497; @@ -63,6 +64,7 @@ abstract contract Addresses { address internal constant eBTC = 0x657e8C867D8B37dCC18fA4Caead9C45EB088C642; address internal constant solvBTC = 0x7A56E1C57C7475CCf742a1832B028F0456652F97; address internal constant pumpBTC = 0xF469fBD2abcd6B9de8E169d128226C0Fc90a012e; + address internal constant xAUt = 0x68749665FF8D2d112Fa859AA293F07A622782F38; address internal constant PT_corn_LBTC_26DEC2024 = 0x332A8ee60EdFf0a11CF3994b1b846BBC27d3DcD6; address internal constant PT_eBTC_26DEC2024 = 0xB997B3418935A1Df0F914Ee901ec83927c1509A0; address internal constant PT_corn_pumpBTC_26DEC2024 = 0xa76f0C6e5f286bFF151b891d2A0245077F1Ad74c; @@ -70,14 +72,18 @@ abstract contract Addresses { address internal constant PT_USD0PlusPlus_30JAN2025 = 0x61439b9575278054D69c9176d88FaFaf8319E4b7; address internal constant PT_USD0PlusPlus_26JUN2025 = 0xf696FE29Ef85E892b5926313897D178288faA07e; address internal constant PT_USDe_31JUL2025 = 0x917459337CaAC939D41d7493B3999f571D20D667; + address internal constant PT_USDe_25SEP2025 = 0xBC6736d346a5eBC0dEbc997397912CD9b8FAe10a; address internal constant PT_sUSDe_29MAY2025 = 0xb7de5dFCb74d25c2f21841fbd6230355C50d9308; address internal constant PT_sUSDe_31JULY2025 = 0x3b3fB9C57858EF816833dC91565EFcd85D96f634; + address internal constant PT_sUSDe_25SEP2025 = 0x9F56094C450763769BA0EA9Fe2876070c0fD5F77; address internal constant PT_eUSDe_29MAY2025 = 0x50D2C7992b802Eef16c04FeADAB310f31866a545; address internal constant PT_eUSDe_14AUG2025 = 0x14Bdc3A3AE09f5518b923b69489CBcAfB238e617; address internal constant PT_cUSDO_19JUN2025 = 0x933B9FfEE0Ad3Ef8E4DBb52688ea905826D73755; address internal constant PT_cUSDO_20NOV2025 = 0xB10DA2F9147f9cf2B8826877Cd0c95c18A0f42dc; address internal constant PT_syrupUSDC_28AUG2025 = 0xCcE7D12f683c6dAe700154f0BAdf779C0bA1F89A; address internal constant PT_USDS_14AUG2025 = 0xFfEc096c087C13Cc268497B89A613cACE4DF9A48; + address internal constant PT_tUSDe_25SEP2025 = 0xd0a4B74A6B62aA2b6C02349463D9041606608F36; + address internal constant PT_pUSDe_16OCT2025 = 0xF3f491e5608f8B8a6Fd9E9d66a4a4036d7FD282C; } abstract contract ManageCluster is ManageClusterBase, Addresses {} diff --git a/script/production/mainnet/clusters/PrimeCluster.json b/script/production/mainnet/clusters/PrimeCluster.json index ff3270b2..ae6b5fd4 100644 --- a/script/production/mainnet/clusters/PrimeCluster.json +++ b/script/production/mainnet/clusters/PrimeCluster.json @@ -1,29 +1,32 @@ { "externalVaults": [ "0xF6E2EfDF175e7a91c8847dade42f2d39A9aE57D4", - "0xe3CA8369346A35b0633da9A4Eb48394478C8BEC2" + "0xe3CA8369346A35b0633da9A4Eb48394478C8BEC2", + "0xC51e90b48FD7fBfF316502b85A71e0EBb1ee5238" ], "irms": [ - "0x89bD17660a9AC687e76395eD2e65CA36685e7A23", + "0x001442309E82b3E69d9Cf520e318c62A64FA190c", "0xB47a57e63C7Bb22c97ab7930Fb737d424e9630DA", "0x8a70d5962899B58eacC4d8a62368D490C0e53ad4", "0x3182ddB461934E312eEC21035324243648DdfcD7", "0x3182ddB461934E312eEC21035324243648DdfcD7", "0x8a70d5962899B58eacC4d8a62368D490C0e53ad4", - "0x8a70d5962899B58eacC4d8a62368D490C0e53ad4", "0x3182ddB461934E312eEC21035324243648DdfcD7", - "0x8a70d5962899B58eacC4d8a62368D490C0e53ad4", "0x3182ddB461934E312eEC21035324243648DdfcD7", - "0x287732F543a83199Dd522736EAFEB304fC0c1EA3", - "0x287732F543a83199Dd522736EAFEB304fC0c1EA3", - "0x287732F543a83199Dd522736EAFEB304fC0c1EA3", - "0x287732F543a83199Dd522736EAFEB304fC0c1EA3", + "0x029841cBB4c939C569961BC3Ed0DB44AFde278F7", + "0x029841cBB4c939C569961BC3Ed0DB44AFde278F7", + "0x029841cBB4c939C569961BC3Ed0DB44AFde278F7", + "0x029841cBB4c939C569961BC3Ed0DB44AFde278F7", "0x27719353Be37091369571F15e51e39C948ee84c2", - "0x287732F543a83199Dd522736EAFEB304fC0c1EA3", - "0x287732F543a83199Dd522736EAFEB304fC0c1EA3", + "0x029841cBB4c939C569961BC3Ed0DB44AFde278F7", + "0x029841cBB4c939C569961BC3Ed0DB44AFde278F7", + "0x029841cBB4c939C569961BC3Ed0DB44AFde278F7", + "0x0000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000", "0xaf7D5898DD56A5690e4AE9DB7Ed8656f4F38ea72", "0xFc85FFB8C3A3d7564966Ea7d3A1354322dd90778", - "0x4A0D00E0849F7DeB0Bec8259290698da7C975170" + "0x4A0D00E0849F7DeB0Bec8259290698da7C975170", + "0x0000000000000000000000000000000000000000" ], "oracleRouters": [ "0x83B3b76873D36A28440cF53371dF404c42497136", @@ -45,6 +48,8 @@ "0x83B3b76873D36A28440cF53371dF404c42497136", "0x83B3b76873D36A28440cF53371dF404c42497136", "0x83B3b76873D36A28440cF53371dF404c42497136", + "0x83B3b76873D36A28440cF53371dF404c42497136", + "0x83B3b76873D36A28440cF53371dF404c42497136", "0x83B3b76873D36A28440cF53371dF404c42497136" ], "stubOracle": "0xbF045915CaF2C309A5bA1A3Ae024EFD8E54fB66c", @@ -55,9 +60,7 @@ "0xe846ca062aB869b66aE8DcD811973f628BA82eAf", "0xE88e44C2C7dfc9bcb86e380d29375ccD6cd85406", "0x0D1B386187be8e96680bbddBf7Bc05FC737f81b8", - "0xddd082d01852EFccEc0DB5477F41f530Ecb0C136", "0x1924D7fab80d0623f0836Cbf5258a7fa734EE9D9", - "0x9Dfe12dBd94eb8294b047Fabe3142C5d7178071b", "0xA28C23a459fF8773EB4dBe0e7250d93F79F1Fe2B", "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", "0x313603FA690301b0CaeEf8069c065862f9162162", @@ -66,8 +69,12 @@ "0x1e548CfcE5FCF17247E024eF06d32A01841fF404", "0x328646cdfBaD730432620d845B8F5A2f7D786C01", "0xc2d36F41841B420937643dcccbEa8163D4F59B6c", + "0x22eed7C25A35D40255cd80d3B67A2F8742f94443", + "0x6bE9e82B25987Ce66AcD89130fEe494EDd0473AE", + "0xee944C7Dd107617550EC11AFCF652e14E7670A37", "0x998D761eC1BAdaCeb064624cc3A1d37A46C88bA4", "0x056f3a2E41d2778D3a0c0714439c53af2987718E", - "0xbC35161043EE2D74816d421EfD6a45fDa73B050A" + "0xbC35161043EE2D74816d421EfD6a45fDa73B050A", + "0x5A96128c18018a2cEf539f46Bbed037DAD3cAAe8" ] } \ No newline at end of file diff --git a/script/production/mainnet/clusters/PrimeCluster.s.sol b/script/production/mainnet/clusters/PrimeCluster.s.sol index 700e1618..b181d927 100644 --- a/script/production/mainnet/clusters/PrimeCluster.s.sol +++ b/script/production/mainnet/clusters/PrimeCluster.s.sol @@ -21,9 +21,7 @@ contract Cluster is ManageCluster { weETH, ezETH, RETH, - mETH, rsETH, - ETHx, tETH, USDC, USDT, @@ -32,9 +30,13 @@ contract Cluster is ManageCluster { sUSDS, USDtb, rlUSD, + USDe, + sUSDe, + syrupUSDC, WBTC, cbBTC, - LBTC + LBTC, + xAUt ]; } @@ -76,75 +78,84 @@ contract Cluster is ManageCluster { // External Vaults Registry, the string should be preceeded by "ExternalVault|" prefix. this is in order to resolve // the asset (vault) in the oracle router. // in case the adapter is not present in the Adapter Registry, the adapter address can be passed instead in form of a string. - cluster.oracleProviders[WETH ] = "ChainlinkOracle"; - cluster.oracleProviders[wstETH ] = "CrossAdapter=LidoFundamentalOracle+ChainlinkOracle"; - cluster.oracleProviders[cbETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; - cluster.oracleProviders[weETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; - cluster.oracleProviders[ezETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; - cluster.oracleProviders[RETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; - cluster.oracleProviders[mETH ] = "CrossAdapter=PythOracle+ChainlinkOracle"; - cluster.oracleProviders[rsETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; - cluster.oracleProviders[ETHx ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; - cluster.oracleProviders[tETH ] = "0x74b77011c244bd7edff34e4cbf23fe41defa313d"; - cluster.oracleProviders[USDC ] = "ChainlinkOracle"; - cluster.oracleProviders[USDT ] = "ChainlinkOracle"; - cluster.oracleProviders[wM ] = "FixedRateOracle"; - cluster.oracleProviders[USDS ] = "ChainlinkOracle"; - cluster.oracleProviders[sUSDS ] = "ExternalVault|ChainlinkOracle"; - cluster.oracleProviders[USDtb ] = "FixedRateOracle"; - cluster.oracleProviders[rlUSD ] = "FixedRateOracle"; - cluster.oracleProviders[WBTC ] = "0x8e8cfcbe490da27032a6edacb6a8436be904cd4e"; // "CrossAdapter=FixedRateOracle+ChainlinkOracle"; - cluster.oracleProviders[cbBTC ] = "0xd0156a894f2d14b127a8c37360d6879891f62efa"; // "CrossAdapter=FixedRateOracle+ChainlinkOracle"; - cluster.oracleProviders[LBTC ] = "CrossAdapter=ChainlinkOracle+ChainlinkOracle"; + + cluster.oracleProviders[WETH ] = "ChainlinkOracle"; + cluster.oracleProviders[wstETH ] = "CrossAdapter=LidoFundamentalOracle+ChainlinkOracle"; + cluster.oracleProviders[cbETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; + cluster.oracleProviders[weETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; + cluster.oracleProviders[ezETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; + cluster.oracleProviders[RETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; + cluster.oracleProviders[rsETH ] = "CrossAdapter=RateProviderOracle+ChainlinkOracle"; + cluster.oracleProviders[tETH ] = "0x74b77011c244bd7edff34e4cbf23fe41defa313d"; + cluster.oracleProviders[USDC ] = "ChainlinkOracle"; + cluster.oracleProviders[USDT ] = "ChainlinkOracle"; + cluster.oracleProviders[wM ] = "FixedRateOracle"; + cluster.oracleProviders[USDS ] = "ChainlinkOracle"; + cluster.oracleProviders[sUSDS ] = "ExternalVault|ChainlinkOracle"; + cluster.oracleProviders[USDtb ] = "FixedRateOracle"; + cluster.oracleProviders[rlUSD ] = "FixedRateOracle"; + cluster.oracleProviders[USDe ] = "0x8211B9ae40b06d3Db0215E520F232184Af355378"; + cluster.oracleProviders[sUSDe ] = "ExternalVault|0x8211B9ae40b06d3Db0215E520F232184Af355378"; + cluster.oracleProviders[syrupUSDC] = "ExternalVault|ChainlinkOracle"; + cluster.oracleProviders[WBTC ] = "0x8e8cfcbe490da27032a6edacb6a8436be904cd4e"; // "CrossAdapter=FixedRateOracle+ChainlinkOracle"; + cluster.oracleProviders[cbBTC ] = "0xd0156a894f2d14b127a8c37360d6879891f62efa"; // "CrossAdapter=FixedRateOracle+ChainlinkOracle"; + cluster.oracleProviders[LBTC ] = "CrossAdapter=ChainlinkOracle+ChainlinkOracle"; + cluster.oracleProviders[xAUt ] = "0x6cbca9757201680f65bc10022395c224b490f699"; + + cluster.oracleProviders[sBUIDL ] = "ExternalVault|0x1CF7192cF739675186653D453828C0A670ed5Cd9"; // define supply caps here. 0 means no supply can occur, type(uint256).max means no cap defined hence max amount - cluster.supplyCaps[WETH ] = 100_000; - cluster.supplyCaps[wstETH ] = 12_500; - cluster.supplyCaps[cbETH ] = 12_500; - cluster.supplyCaps[weETH ] = 18_000; - cluster.supplyCaps[ezETH ] = 13_000; - cluster.supplyCaps[RETH ] = 6_250; - cluster.supplyCaps[mETH ] = 6_250; - cluster.supplyCaps[rsETH ] = 36_000; - cluster.supplyCaps[ETHx ] = 2_500; - cluster.supplyCaps[tETH ] = 18_000; - cluster.supplyCaps[USDC ] = 75_000_000; - cluster.supplyCaps[USDT ] = 50_000_000; - cluster.supplyCaps[wM ] = 5_000_000; - cluster.supplyCaps[USDS ] = 10_000_000; - cluster.supplyCaps[sUSDS ] = 8_000_000; - cluster.supplyCaps[USDtb ] = 20_000_000; - cluster.supplyCaps[rlUSD ] = 25_000_000; - cluster.supplyCaps[WBTC ] = 600; - cluster.supplyCaps[cbBTC ] = 500; - cluster.supplyCaps[LBTC ] = 600; + cluster.supplyCaps[WETH ] = 75_000; + cluster.supplyCaps[wstETH ] = 10_000; + cluster.supplyCaps[cbETH ] = 2_300; + cluster.supplyCaps[weETH ] = 13_500; + cluster.supplyCaps[ezETH ] = 9_750; + cluster.supplyCaps[RETH ] = 1_100; + cluster.supplyCaps[rsETH ] = 27_000; + cluster.supplyCaps[tETH ] = 9_400; + cluster.supplyCaps[USDC ] = 75_000_000; + cluster.supplyCaps[USDT ] = 50_000_000; + cluster.supplyCaps[wM ] = 5_000_000; + cluster.supplyCaps[USDS ] = 2_500_000; + cluster.supplyCaps[sUSDS ] = 4_000_000; + cluster.supplyCaps[USDtb ] = 20_000_000; + cluster.supplyCaps[rlUSD ] = 25_000_000; + cluster.supplyCaps[USDe ] = 25_000_000; + cluster.supplyCaps[sUSDe ] = 8_000_000; + cluster.supplyCaps[syrupUSDC ] = 20_000_000; + cluster.supplyCaps[WBTC ] = 600; + cluster.supplyCaps[cbBTC ] = 500; + cluster.supplyCaps[LBTC ] = 600; + cluster.supplyCaps[xAUt ] = 200; // define borrow caps here. 0 means no borrow can occur, type(uint256).max means no cap defined hence max amount - cluster.borrowCaps[WETH ] = 90_000; - cluster.borrowCaps[wstETH ] = 5_000; - cluster.borrowCaps[cbETH ] = 5_000; - cluster.borrowCaps[weETH ] = 4_500; - cluster.borrowCaps[ezETH ] = 3_120; - cluster.borrowCaps[RETH ] = 2_500; - cluster.borrowCaps[mETH ] = 0; - cluster.borrowCaps[rsETH ] = 9_000; - cluster.borrowCaps[ETHx ] = 0; - cluster.borrowCaps[tETH ] = 3_000; - cluster.borrowCaps[USDC ] = 67_500_000; - cluster.borrowCaps[USDT ] = 45_000_000; - cluster.borrowCaps[wM ] = 4_500_000; - cluster.borrowCaps[USDS ] = 9_000_000; - cluster.borrowCaps[sUSDS ] = 3_200_000; - cluster.borrowCaps[USDtb ] = 18_000_000; - cluster.borrowCaps[rlUSD ] = 23_000_000; - cluster.borrowCaps[WBTC ] = 510; - cluster.borrowCaps[cbBTC ] = 425; - cluster.borrowCaps[LBTC ] = 150; + cluster.borrowCaps[WETH ] = 67_500; + cluster.borrowCaps[wstETH ] = 7_500; + cluster.borrowCaps[cbETH ] = 900; + cluster.borrowCaps[weETH ] = 3_380; + cluster.borrowCaps[ezETH ] = 2_340; + cluster.borrowCaps[RETH ] = 400; + cluster.borrowCaps[rsETH ] = 6_750; + cluster.borrowCaps[tETH ] = 1_600; + cluster.borrowCaps[USDC ] = 67_500_000; + cluster.borrowCaps[USDT ] = 45_000_000; + cluster.borrowCaps[wM ] = 4_500_000; + cluster.borrowCaps[USDS ] = 2_250_000; + cluster.borrowCaps[sUSDS ] = 1_600_000; + cluster.borrowCaps[USDtb ] = 18_000_000; + cluster.borrowCaps[rlUSD ] = 23_000_000; + cluster.borrowCaps[USDe ] = 22_500_000; + cluster.borrowCaps[sUSDe ] = type(uint256).max; + cluster.borrowCaps[syrupUSDC ] = type(uint256).max; + cluster.borrowCaps[WBTC ] = 510; + cluster.borrowCaps[cbBTC ] = 425; + cluster.borrowCaps[LBTC ] = 150; + cluster.borrowCaps[xAUt ] = type(uint256).max; // define IRM classes here and assign them to the assets { - // Base=0.00% APY, Kink(90.00%)=2.60% APY Max=40.00% APY - uint256[4] memory irmETH = [uint256(0), uint256(210421597), uint256(22931495218), uint256(3865470566)]; + // Base=0.00% APY, Kink(90.00%)=2.85% APY Max=40.00% APY + uint256[4] memory irmETH = [uint256(0), uint256(230372693), uint256(22751935351), uint256(3865470566)]; // Base=0% APY, Kink(85.00%)=0.50% APY Max=80.00% APY uint256[4] memory irmWSTETH = [uint256(0), uint256(43292497), uint256(28666371159), uint256(3650722201)]; @@ -158,8 +169,8 @@ contract Cluster is ManageCluster { // Base=0% APY, Kink(25%)=4.60% APY Max=848.77% APY uint256[4] memory irmETH_LRT = [uint256(0), uint256(1327273625), uint256(21691866441), uint256(1073741824)]; - // Base=0.00% APY, Kink(90.00%)=5.50% APY Max=40.00% APY - uint256[4] memory irmUSD_1 = [uint256(0), uint256(438921808), uint256(20874993316), uint256(3865470566)]; + // Base=0.00% APY, Kink(90.00%)=6.50% APY Max=13.00% APY + uint256[4] memory irmUSD_1 = [uint256(0), uint256(516261061), uint256(4371001016), uint256(3865470566)]; // Base=0% APY, Kink(40%)=2.79% APY Max=145.96% APY uint256[4] memory irmRWA_YLD_1 = [uint256(0), uint256(507574932), uint256(10728765229), uint256(1717986918)]; @@ -176,9 +187,7 @@ contract Cluster is ManageCluster { cluster.kinkIRMParams[weETH ] = irmETH_LRT; cluster.kinkIRMParams[ezETH ] = irmETH_LRT; cluster.kinkIRMParams[RETH ] = irmETH_LST; - cluster.kinkIRMParams[mETH ] = irmETH_LST; cluster.kinkIRMParams[rsETH ] = irmETH_LRT; - cluster.kinkIRMParams[ETHx ] = irmETH_LST; cluster.kinkIRMParams[tETH ] = irmETH_LRT; cluster.kinkIRMParams[USDC ] = irmUSD_1; cluster.kinkIRMParams[USDT ] = irmUSD_1; @@ -187,6 +196,7 @@ contract Cluster is ManageCluster { cluster.kinkIRMParams[sUSDS ] = irmRWA_YLD_1; cluster.kinkIRMParams[USDtb ] = irmUSD_1; cluster.kinkIRMParams[rlUSD ] = irmUSD_1; + cluster.kinkIRMParams[USDe ] = irmUSD_1; cluster.kinkIRMParams[WBTC ] = irmBTC; cluster.kinkIRMParams[cbBTC ] = irmCBBTC; cluster.kinkIRMParams[LBTC ] = irmLBTC; @@ -201,36 +211,39 @@ contract Cluster is ManageCluster { // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - // WETH wstETH cbETH weETH ezETH RETH mETH rsETH ETHx tETH USDC USDT wM USDS sUSDS USDtb rlUSD WBTC cbBTC LBTC - /* 0 WETH */ [uint16(0.00e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.93e4, 0.85e4, 0.85e4, 0.85e4, 0.85e4, 0.00e4, 0.85e4, 0.85e4, 0.73e4, 0.78e4, 0.78e4], - /* 1 wstETH */ [uint16(0.95e4), 0.00e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.93e4, 0.83e4, 0.83e4, 0.83e4, 0.83e4, 0.00e4, 0.87e4, 0.87e4, 0.72e4, 0.77e4, 0.77e4], - /* 2 cbETH */ [uint16(0.93e4), 0.93e4, 0.00e4, 0.92e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.93e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.80e4, 0.80e4, 0.70e4, 0.75e4, 0.75e4], - /* 3 weETH */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.93e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.80e4, 0.80e4, 0.70e4, 0.75e4, 0.75e4], - /* 4 ezETH */ [uint16(0.93e4), 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.90e4, 0.00e4, 0.90e4, 0.00e4, 0.90e4, 0.77e4, 0.77e4, 0.77e4, 0.77e4, 0.00e4, 0.77e4, 0.77e4, 0.67e4, 0.72e4, 0.72e4], - /* 5 RETH */ [uint16(0.95e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4, 0.90e4, 0.00e4, 0.90e4, 0.77e4, 0.77e4, 0.77e4, 0.77e4, 0.00e4, 0.77e4, 0.77e4, 0.67e4, 0.72e4, 0.72e4], - /* 6 mETH */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 7 rsETH */ [uint16(0.93e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4, 0.00e4, 0.90e4, 0.77e4, 0.77e4, 0.77e4, 0.77e4, 0.00e4, 0.77e4, 0.77e4, 0.67e4, 0.72e4, 0.72e4], - /* 8 ETHx */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 9 tETH */ [uint16(0.93e4), 0.93e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.90e4, 0.00e4, 0.00e4, 0.77e4, 0.77e4, 0.77e4, 0.77e4, 0.00e4, 0.77e4, 0.77e4, 0.67e4, 0.72e4, 0.72e4], - /* 10 USDC */ [uint16(0.87e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.80e4, 0.00e4, 0.80e4, 0.00e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.95e4, 0.95e4, 0.82e4, 0.80e4, 0.80e4], - /* 11 USDT */ [uint16(0.87e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.80e4, 0.00e4, 0.80e4, 0.95e4, 0.00e4, 0.95e4, 0.95e4, 0.00e4, 0.95e4, 0.95e4, 0.82e4, 0.80e4, 0.80e4], - /* 12 wM */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.00e4, 0.70e4, 0.00e4, 0.70e4, 0.90e4, 0.90e4, 0.00e4, 0.90e4, 0.00e4, 0.90e4, 0.00e4, 0.60e4, 0.65e4, 0.65e4], - /* 13 USDS */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.00e4, 0.70e4, 0.00e4, 0.70e4, 0.94e4, 0.94e4, 0.94e4, 0.00e4, 0.00e4, 0.94e4, 0.94e4, 0.75e4, 0.80e4, 0.80e4], - /* 14 sUSDS */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.94e4, 0.94e4, 0.94e4, 0.94e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 15 USDtb */ [uint16(0.87e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.80e4, 0.00e4, 0.80e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.00e4, 0.94e4, 0.82e4, 0.80e4, 0.80e4], - /* 16 rlUSD */ [uint16(0.87e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.80e4, 0.00e4, 0.80e4, 0.95e4, 0.95e4, 0.00e4, 0.95e4, 0.00e4, 0.95e4, 0.00e4, 0.82e4, 0.80e4, 0.80e4], - /* 17 WBTC */ [uint16(0.82e4), 0.80e4, 0.80e4, 0.77e4, 0.77e4, 0.80e4, 0.00e4, 0.77e4, 0.00e4, 0.77e4, 0.86e4, 0.86e4, 0.86e4, 0.86e4, 0.00e4, 0.86e4, 0.86e4, 0.00e4, 0.90e4, 0.90e4], - /* 18 cbBTC */ [uint16(0.82e4), 0.80e4, 0.80e4, 0.77e4, 0.77e4, 0.80e4, 0.00e4, 0.77e4, 0.00e4, 0.77e4, 0.86e4, 0.86e4, 0.86e4, 0.86e4, 0.00e4, 0.86e4, 0.86e4, 0.90e4, 0.00e4, 0.90e4], - /* 19 LBTC */ [uint16(0.80e4), 0.78e4, 0.78e4, 0.75e4, 0.75e4, 0.78e4, 0.00e4, 0.75e4, 0.00e4, 0.75e4, 0.84e4, 0.84e4, 0.84e4, 0.84e4, 0.00e4, 0.84e4, 0.84e4, 0.90e4, 0.90e4, 0.00e4] + // WETH wstETH cbETH weETH ezETH RETH rsETH tETH USDC USDT wM USDS sUSDS USDtb rlUSD USDe sUSDe syrupUSDC WBTC cbBTC LBTC xAUt + /* 0 WETH */ [uint16(0.00e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.85e4, 0.85e4, 0.85e4, 0.85e4, 0.00e4, 0.85e4, 0.85e4, 0.83e4, 0.00e4, 0.00e4, 0.73e4, 0.78e4, 0.78e4, 0.00e4], + /* 1 wstETH */ [uint16(0.95e4), 0.00e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.83e4, 0.83e4, 0.83e4, 0.83e4, 0.00e4, 0.87e4, 0.87e4, 0.81e4, 0.00e4, 0.00e4, 0.72e4, 0.77e4, 0.77e4, 0.00e4], + /* 2 cbETH */ [uint16(0.93e4), 0.93e4, 0.00e4, 0.92e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.80e4, 0.80e4, 0.78e4, 0.00e4, 0.00e4, 0.70e4, 0.75e4, 0.75e4, 0.00e4], + /* 3 weETH */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.80e4, 0.80e4, 0.78e4, 0.00e4, 0.00e4, 0.70e4, 0.75e4, 0.75e4, 0.00e4], + /* 4 ezETH */ [uint16(0.93e4), 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.90e4, 0.90e4, 0.90e4, 0.77e4, 0.77e4, 0.77e4, 0.77e4, 0.00e4, 0.77e4, 0.77e4, 0.75e4, 0.00e4, 0.00e4, 0.67e4, 0.72e4, 0.72e4, 0.00e4], + /* 5 RETH */ [uint16(0.95e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.90e4, 0.90e4, 0.77e4, 0.77e4, 0.77e4, 0.77e4, 0.00e4, 0.77e4, 0.77e4, 0.75e4, 0.00e4, 0.00e4, 0.67e4, 0.72e4, 0.72e4, 0.00e4], + /* 6 rsETH */ [uint16(0.93e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.90e4, 0.77e4, 0.77e4, 0.77e4, 0.77e4, 0.00e4, 0.77e4, 0.77e4, 0.75e4, 0.00e4, 0.00e4, 0.67e4, 0.72e4, 0.72e4, 0.00e4], + /* 7 tETH */ [uint16(0.93e4), 0.93e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.77e4, 0.77e4, 0.77e4, 0.77e4, 0.00e4, 0.77e4, 0.77e4, 0.75e4, 0.00e4, 0.00e4, 0.67e4, 0.72e4, 0.72e4, 0.00e4], + /* 8 USDC */ [uint16(0.87e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.00e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.95e4, 0.95e4, 0.93e4, 0.00e4, 0.00e4, 0.82e4, 0.80e4, 0.80e4, 0.00e4], + /* 9 USDT */ [uint16(0.87e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.95e4, 0.00e4, 0.95e4, 0.95e4, 0.00e4, 0.95e4, 0.95e4, 0.93e4, 0.00e4, 0.00e4, 0.82e4, 0.80e4, 0.80e4, 0.00e4], + /* 10 wM */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.90e4, 0.90e4, 0.00e4, 0.90e4, 0.00e4, 0.90e4, 0.00e4, 0.88e4, 0.00e4, 0.00e4, 0.60e4, 0.65e4, 0.65e4, 0.00e4], + /* 11 USDS */ [uint16(0.75e4), 0.73e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.70e4, 0.94e4, 0.94e4, 0.94e4, 0.00e4, 0.00e4, 0.94e4, 0.94e4, 0.93e4, 0.00e4, 0.00e4, 0.75e4, 0.80e4, 0.80e4, 0.00e4], + /* 12 sUSDS */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.94e4, 0.94e4, 0.94e4, 0.94e4, 0.00e4, 0.00e4, 0.00e4, 0.92e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 13 USDtb */ [uint16(0.87e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.00e4, 0.94e4, 0.93e4, 0.00e4, 0.00e4, 0.82e4, 0.80e4, 0.80e4, 0.00e4], + /* 14 rlUSD */ [uint16(0.87e4), 0.83e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.80e4, 0.95e4, 0.95e4, 0.00e4, 0.95e4, 0.00e4, 0.95e4, 0.00e4, 0.93e4, 0.00e4, 0.00e4, 0.82e4, 0.80e4, 0.80e4, 0.00e4], + /* 15 USDe */ [uint16(0.73e4), 0.71e4, 0.68e4, 0.68e4, 0.68e4, 0.68e4, 0.68e4, 0.68e4, 0.92e4, 0.92e4, 0.92e4, 0.92e4, 0.00e4, 0.92e4, 0.92e4, 0.00e4, 0.00e4, 0.00e4, 0.73e4, 0.78e4, 0.78e4, 0.00e4], + /* 16 sUSDe */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.92e4, 0.92e4, 0.00e4, 0.92e4, 0.00e4, 0.00e4, 0.00e4, 0.92e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 17syrupUSDC*/ [uint16(0.80e4), 0.78e4, 0.75e4, 0.75e4, 0.72e4, 0.72e4, 0.72e4, 0.72e4, 0.90e4, 0.90e4, 0.85e4, 0.89e4, 0.00e4, 0.90e4, 0.90e4, 0.87e4, 0.00e4, 0.00e4, 0.81e4, 0.81e4, 0.79e4, 0.00e4], + /* 18 WBTC */ [uint16(0.82e4), 0.80e4, 0.80e4, 0.77e4, 0.77e4, 0.80e4, 0.77e4, 0.77e4, 0.86e4, 0.86e4, 0.86e4, 0.86e4, 0.00e4, 0.86e4, 0.86e4, 0.84e4, 0.00e4, 0.00e4, 0.00e4, 0.90e4, 0.90e4, 0.00e4], + /* 19 cbBTC */ [uint16(0.82e4), 0.80e4, 0.80e4, 0.77e4, 0.77e4, 0.80e4, 0.77e4, 0.77e4, 0.86e4, 0.86e4, 0.86e4, 0.86e4, 0.00e4, 0.86e4, 0.86e4, 0.84e4, 0.00e4, 0.00e4, 0.90e4, 0.00e4, 0.90e4, 0.00e4], + /* 20 LBTC */ [uint16(0.80e4), 0.78e4, 0.78e4, 0.75e4, 0.75e4, 0.78e4, 0.75e4, 0.75e4, 0.84e4, 0.84e4, 0.84e4, 0.84e4, 0.00e4, 0.84e4, 0.84e4, 0.82e4, 0.00e4, 0.00e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4], + /* 21 xAUt */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.75e4, 0.75e4, 0.00e4, 0.75e4, 0.00e4, 0.75e4, 0.75e4, 0.73e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4] ]; // define external ltvs here. columns are liability vaults, rows are collateral vaults. // double check the order of collaterals against the order of externalVaults in the addresses file cluster.externalLTVs = [ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - // WETH wstETH cbETH weETH ezETH RETH mETH rsETH ETHx tETH USDC USDT wM USDS sUSDS USDtb rlUSD WBTC cbBTC LBTC - /* 1 Escrow wstETH */ [uint16(0.95e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.87e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 2 Escrow sUSDS */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.94e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4] + // WETH wstETH cbETH weETH ezETH RETH rsETH tETH USDC USDT wM USDS sUSDS USDtb rlUSD USDe sUSDe syrupUSDC WBTC cbBTC LBTC xAUt + /* 1 Escrow wstETH */ [uint16(0.95e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.87e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 2 Escrow sUSDS */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.94e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 3 RWA sBUIDL */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4] ]; } diff --git a/script/production/mainnet/clusters/RWACluster.json b/script/production/mainnet/clusters/RWACluster.json index 3a798c62..2fd48feb 100644 --- a/script/production/mainnet/clusters/RWACluster.json +++ b/script/production/mainnet/clusters/RWACluster.json @@ -4,7 +4,7 @@ "0x2fF731d425d2B0be3d9CC2123c5B412CA5119CA5", "0x2fF731d425d2B0be3d9CC2123c5B412CA5119CA5", "0x2fF731d425d2B0be3d9CC2123c5B412CA5119CA5", - "0x2fF731d425d2B0be3d9CC2123c5B412CA5119CA5" + "0x0000000000000000000000000000000000000000" ], "oracleRouters": [ "0x3c0D5070449D29E7fa851C319Ed8287fa99fFFF5", diff --git a/script/production/mainnet/clusters/RWACluster.s.sol b/script/production/mainnet/clusters/RWACluster.s.sol index e1e895d4..7a00e636 100644 --- a/script/production/mainnet/clusters/RWACluster.s.sol +++ b/script/production/mainnet/clusters/RWACluster.s.sol @@ -64,13 +64,13 @@ contract Cluster is ManageCluster { cluster.supplyCaps[USDC ] = 100_000_000; cluster.supplyCaps[USDT ] = 100_000_000; cluster.supplyCaps[rlUSD ] = 100_000_000; - cluster.supplyCaps[sBUIDL] = 100_000_000; + cluster.supplyCaps[sBUIDL] = 1_100_000; // define borrow caps here. 0 means no borrow can occur, type(uint256).max means no cap defined hence max amount cluster.borrowCaps[USDC ] = 90_000_00; cluster.borrowCaps[USDT ] = 90_000_00; cluster.borrowCaps[rlUSD ] = 90_000_00; - cluster.borrowCaps[sBUIDL] = 90_000_00; + cluster.borrowCaps[sBUIDL] = type(uint256).max; // define IRM classes here and assign them to the assets { @@ -80,7 +80,6 @@ contract Cluster is ManageCluster { cluster.kinkIRMParams[USDC ] = irm; cluster.kinkIRMParams[USDT ] = irm; cluster.kinkIRMParams[rlUSD ] = irm; - cluster.kinkIRMParams[sBUIDL] = irm; } // define the ramp duration to be used, in case the liquidation LTVs have to be ramped down diff --git a/script/production/mainnet/clusters/YieldCluster.json b/script/production/mainnet/clusters/YieldCluster.json index 80eba4ea..737dd93f 100644 --- a/script/production/mainnet/clusters/YieldCluster.json +++ b/script/production/mainnet/clusters/YieldCluster.json @@ -1,25 +1,26 @@ { "externalVaults": [ "0x797DD80692c3b2dAdabCe8e30C07fDE5307D48a9", - "0x313603FA690301b0CaeEf8069c065862f9162162" + "0x313603FA690301b0CaeEf8069c065862f9162162", + "0xC51e90b48FD7fBfF316502b85A71e0EBb1ee5238" ], "irms": [ - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", + "0xF07f31E9E2DB26e449c53B7eb9371C49A3B17737", + "0xF07f31E9E2DB26e449c53B7eb9371C49A3B17737", + "0xa3140381CE3AE846D421796d40aFE04f20F83D1F", + "0xa3140381CE3AE846D421796d40aFE04f20F83D1F", + "0xa3140381CE3AE846D421796d40aFE04f20F83D1F", + "0x9254f9093fA0e02F63De30EabfEB9E9f27C23F87", "0x0c2f4b60cB0Cbec418257D30227BC010F286a491", - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", + "0x9254f9093fA0e02F63De30EabfEB9E9f27C23F87", "0x0c2f4b60cB0Cbec418257D30227BC010F286a491", - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", + "0x9254f9093fA0e02F63De30EabfEB9E9f27C23F87", "0x0c2f4b60cB0Cbec418257D30227BC010F286a491", - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", - "0x31cD485817421012D85BF72ece740baAE3c0DeDe", + "0xa3140381CE3AE846D421796d40aFE04f20F83D1F", + "0x8e2A8874401E1231825cf46bA27eC3aa195DDaf4", "0x211ab5CD0e3EFF8997d4c673A1De39de30b883cA", - "0xAef49dCbd4970C74a237A7d23bb2Ef4c73C4c564", - "0x49C1B5D9aF507aBe37CEee8e4ac27425415a1b03", + "0xa3140381CE3AE846D421796d40aFE04f20F83D1F", + "0x8e2A8874401E1231825cf46bA27eC3aa195DDaf4", "0x0000000000000000000000000000000000000000", "0xc27214e272AE6D3012feA808c79A41BF4013F044", "0x0c2f4b60cB0Cbec418257D30227BC010F286a491", @@ -32,8 +33,6 @@ "0x0000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000" ], "oracleRouters": [ @@ -65,8 +64,6 @@ "0xA77a6CeABD36B261C4DDeA5A7528EFed7299F627", "0xA77a6CeABD36B261C4DDeA5A7528EFed7299F627", "0xA77a6CeABD36B261C4DDeA5A7528EFed7299F627", - "0xA77a6CeABD36B261C4DDeA5A7528EFed7299F627", - "0xA77a6CeABD36B261C4DDeA5A7528EFed7299F627", "0xA77a6CeABD36B261C4DDeA5A7528EFed7299F627" ], "stubOracle": "0xbF045915CaF2C309A5bA1A3Ae024EFD8E54fB66c", @@ -90,17 +87,15 @@ "0x16d84F98765Ed86501a052D47E76BFefb2D36206", "0xe0f8c07282bDc7831bAea448c2F6bFEc8eeBDcA7", "0x8E35E3aa6eFBC8D11Eb4F3b743f180257C80e517", - "0xEF1d264dDcF1ebc0485d31daEbE5C5698942F55F", - "0x0F81E34a5AD7929eB863F97F4217A182923FCEfb", - "0x29847715A8D621BBD34DB7380cE8164F69Be88A7", "0x43356281a62dc8712C7186Ca02BA3aD906B6181D", - "0xb7FC5ECF8E9F1DdBd8e039e189c7BBC575be23Ea", + "0xb53b4B2590457bE63E1DCdAffa6a18ECd44D96D2", "0xCa452aFF8729c9125EE448e60E8099FF6F4C3cf3", - "0x1f193dB3d813aF14927577817ae4FC3a42f25694", + "0xA9902f9210059171C52b2721424E00f48821dcf3", "0x5e761084c253743268CdbcCc433bDd33C94c82C9", - "0xA2f92e2db62c13409E3B8Aa9f5660Fa2C7E909FA", "0xaabc07A47D2a63a9b06A7924a0780c2F3cAE7bf9", "0xa626c933E9fc8d37Cf2d8217F49309FDb0AA21c5", - "0x0934554feefa7e264C349cDe626933b908166635" + "0x0934554feefa7e264C349cDe626933b908166635", + "0xbF34Cf6F1C098231E16D7Be38a2aE13EfE9b92d3", + "0x2f94Bbe20ECa1e3f9332aA93A90920a0a5be0728" ] } \ No newline at end of file diff --git a/script/production/mainnet/clusters/YieldCluster.s.sol b/script/production/mainnet/clusters/YieldCluster.s.sol index 7a7d5300..f3923976 100644 --- a/script/production/mainnet/clusters/YieldCluster.s.sol +++ b/script/production/mainnet/clusters/YieldCluster.s.sol @@ -36,18 +36,16 @@ contract Cluster is ManageCluster { srUSD, syrupUSDC, mBASIS, - mEDGE, - mMEV, - PT_USD0PlusPlus_26JUN2025, PT_USDe_31JUL2025, - PT_sUSDe_29MAY2025, + PT_USDe_25SEP2025, PT_sUSDe_31JULY2025, - PT_eUSDe_29MAY2025, + PT_sUSDe_25SEP2025, PT_eUSDe_14AUG2025, - PT_cUSDO_19JUN2025, PT_cUSDO_20NOV2025, PT_syrupUSDC_28AUG2025, - PT_USDS_14AUG2025 + PT_USDS_14AUG2025, + PT_tUSDe_25SEP2025, + PT_pUSDe_16OCT2025 ]; } @@ -123,24 +121,24 @@ contract Cluster is ManageCluster { cluster.oracleProviders[srUSD ] = "0xd54bc197150487a40d4ebd4fb215ca4fa996173e"; cluster.oracleProviders[syrupUSDC ] = "ExternalVault|0x6213f24332D35519039f2afa7e3BffE105a37d3F"; cluster.oracleProviders[mBASIS ] = "0xfd63eED8Db6F5Bae46B2860C4B8a8a07eD8BF8bb"; - cluster.oracleProviders[mEDGE ] = "0xc8228b83f1d97a431a48bd9bc3e971c8b418d889"; - cluster.oracleProviders[mMEV ] = "0xf5c2dfd1740d18ad7cf23fba76cc11d877802937"; - cluster.oracleProviders[PT_USD0PlusPlus_26JUN2025] = "CrossAdapter=PendleOracle+PythOracle"; cluster.oracleProviders[PT_USDe_31JUL2025 ] = "0xd9df01449ba6e3a4b2ad2b4e92e9b5d6a7c8b66b"; - cluster.oracleProviders[PT_sUSDe_29MAY2025 ] = "CrossAdapter=PendleOracle+PythOracle"; + cluster.oracleProviders[PT_USDe_25SEP2025 ] = "0x15226E1796C24a635A9662BFF2b8dc6Cc3aAc6bb"; cluster.oracleProviders[PT_sUSDe_31JULY2025 ] = "0x7351d14f0d8ad684302578e3f8f7d2bd161da435"; - cluster.oracleProviders[PT_eUSDe_29MAY2025 ] = "CrossAdapter=PendleUniversalOracle+PythOracle"; + cluster.oracleProviders[PT_sUSDe_25SEP2025 ] = "0xd6B5eba2282836BFBd73d65Bf5203f91cc1179c5"; cluster.oracleProviders[PT_eUSDe_14AUG2025 ] = "0x29e1163590eb05c84747ede225a11ce555b36ce8"; - cluster.oracleProviders[PT_cUSDO_19JUN2025 ] = "CrossAdapter=PendleUniversalOracle+FixedRateOracle"; cluster.oracleProviders[PT_cUSDO_20NOV2025 ] = "0x673222872a407775feab95a7a98f930a2cec53f4"; cluster.oracleProviders[PT_syrupUSDC_28AUG2025 ] = "0xe635E116D38ED5db736E620dD5c839a9A119f3F5"; cluster.oracleProviders[PT_USDS_14AUG2025 ] = "0x011088B8725eef48cAdFf5fb290E186B2AEd83f5"; + cluster.oracleProviders[PT_tUSDe_25SEP2025 ] = "0x130eABADA6f4C663095C8e9E276AB5DA670ffAeD"; + cluster.oracleProviders[PT_pUSDe_16OCT2025 ] = "0xCA5B7044BE73671FD6707C2312cEC7C07556B85f"; + + cluster.oracleProviders[sBUIDL ] = "ExternalVault|0x1CF7192cF739675186653D453828C0A670ed5Cd9"; // define supply caps here. 0 means no supply can occur, type(uint256).max means no cap defined hence max amount - cluster.supplyCaps[USDC ] = 225_000_000; - cluster.supplyCaps[USDT ] = 50_000_000; + cluster.supplyCaps[USDC ] = 300_000_000; + cluster.supplyCaps[USDT ] = 100_000_000; cluster.supplyCaps[PYUSD ] = 5_000_000; - cluster.supplyCaps[rlUSD ] = 150_000_000; + cluster.supplyCaps[rlUSD ] = 200_000_000; cluster.supplyCaps[wM ] = 5_000_000; cluster.supplyCaps[USDS ] = 5_000_000; cluster.supplyCaps[sUSDS ] = 8_000_000; @@ -154,32 +152,30 @@ contract Cluster is ManageCluster { cluster.supplyCaps[USDtb ] = 10_000_000; cluster.supplyCaps[rUSD ] = 30_000_000; cluster.supplyCaps[srUSD ] = 30_000_000; - cluster.supplyCaps[syrupUSDC ] = 10_000_000; - cluster.supplyCaps[mBASIS ] = 3_000_000; - cluster.supplyCaps[mEDGE ] = 0; - cluster.supplyCaps[mMEV ] = 0; - cluster.supplyCaps[PT_USD0PlusPlus_26JUN2025] = 0; - cluster.supplyCaps[PT_USDe_31JUL2025 ] = 8_000_000; - cluster.supplyCaps[PT_sUSDe_29MAY2025 ] = 0; - cluster.supplyCaps[PT_sUSDe_31JULY2025 ] = 40_000_000; - cluster.supplyCaps[PT_eUSDe_29MAY2025 ] = 0; - cluster.supplyCaps[PT_eUSDe_14AUG2025 ] = 70_000_000; - cluster.supplyCaps[PT_cUSDO_19JUN2025 ] = 0; - cluster.supplyCaps[PT_cUSDO_20NOV2025 ] = 100_000_000; - cluster.supplyCaps[PT_syrupUSDC_28AUG2025 ] = 15_000_000; - cluster.supplyCaps[PT_USDS_14AUG2025 ] = 20_000_000; + cluster.supplyCaps[syrupUSDC ] = 5_000_000; + cluster.supplyCaps[mBASIS ] = 0; + cluster.supplyCaps[PT_USDe_31JUL2025 ] = 0; + cluster.supplyCaps[PT_USDe_25SEP2025 ] = 100_000_000; + cluster.supplyCaps[PT_sUSDe_31JULY2025 ] = 0; + cluster.supplyCaps[PT_sUSDe_25SEP2025 ] = 40_000_000; + cluster.supplyCaps[PT_eUSDe_14AUG2025 ] = 0; + cluster.supplyCaps[PT_cUSDO_20NOV2025 ] = 120_000_000; + cluster.supplyCaps[PT_syrupUSDC_28AUG2025 ] = 45_000_000; + cluster.supplyCaps[PT_USDS_14AUG2025 ] = 0; + cluster.supplyCaps[PT_tUSDe_25SEP2025 ] = 60_000_000; + cluster.supplyCaps[PT_pUSDe_16OCT2025 ] = 40_000_000; // define borrow caps here. 0 means no borrow can occur, type(uint256).max means no cap defined hence max amount - cluster.borrowCaps[USDC ] = 200_000_000; - cluster.borrowCaps[USDT ] = 45_000_000; + cluster.borrowCaps[USDC ] = 270_000_000; + cluster.borrowCaps[USDT ] = 75_000_000; cluster.borrowCaps[PYUSD ] = 4_500_000; - cluster.borrowCaps[rlUSD ] = 100_000_000; + cluster.borrowCaps[rlUSD ] = 180_000_000; cluster.borrowCaps[wM ] = 4_500_000; - cluster.borrowCaps[USDS ] = 4_500_000; - cluster.borrowCaps[sUSDS ] = 2_400_000; - cluster.borrowCaps[DAI ] = 4_500_000; - cluster.borrowCaps[sDAI ] = 1_500_000; - cluster.borrowCaps[USD0 ] = 4_500_000; + cluster.borrowCaps[USDS ] = 0; + cluster.borrowCaps[sUSDS ] = 0; + cluster.borrowCaps[DAI ] = 0; + cluster.borrowCaps[sDAI ] = 0; + cluster.borrowCaps[USD0 ] = 0; cluster.borrowCaps[USD0PlusPlus ] = 3_600_000; cluster.borrowCaps[USDe ] = 18_000_000; cluster.borrowCaps[eUSDe ] = 51_000_000; @@ -187,57 +183,58 @@ contract Cluster is ManageCluster { cluster.borrowCaps[USDtb ] = 9_000_000; cluster.borrowCaps[rUSD ] = 27_000_000; cluster.borrowCaps[srUSD ] = type(uint256).max; - cluster.borrowCaps[syrupUSDC ] = 9_000_000; - cluster.borrowCaps[mBASIS ] = 900_000; - cluster.borrowCaps[mEDGE ] = 0; - cluster.borrowCaps[mMEV ] = 0; - cluster.borrowCaps[PT_USD0PlusPlus_26JUN2025] = 0; - cluster.borrowCaps[PT_USDe_31JUL2025 ] = type(uint256).max; - cluster.borrowCaps[PT_sUSDe_29MAY2025 ] = 0; - cluster.borrowCaps[PT_sUSDe_31JULY2025 ] = type(uint256).max; - cluster.borrowCaps[PT_eUSDe_29MAY2025 ] = 0; - cluster.borrowCaps[PT_eUSDe_14AUG2025 ] = type(uint256).max; - cluster.borrowCaps[PT_cUSDO_19JUN2025 ] = 0; + cluster.borrowCaps[syrupUSDC ] = 4_500_000; + cluster.borrowCaps[mBASIS ] = 0; + cluster.borrowCaps[PT_USDe_31JUL2025 ] = 0; + cluster.borrowCaps[PT_USDe_25SEP2025 ] = type(uint256).max; + cluster.borrowCaps[PT_sUSDe_31JULY2025 ] = 0; + cluster.borrowCaps[PT_sUSDe_25SEP2025 ] = type(uint256).max; + cluster.borrowCaps[PT_eUSDe_14AUG2025 ] = 0; cluster.borrowCaps[PT_cUSDO_20NOV2025 ] = type(uint256).max; cluster.borrowCaps[PT_syrupUSDC_28AUG2025 ] = type(uint256).max; - cluster.borrowCaps[PT_USDS_14AUG2025 ] = type(uint256).max; + cluster.borrowCaps[PT_USDS_14AUG2025 ] = 0; + cluster.borrowCaps[PT_tUSDe_25SEP2025 ] = type(uint256).max; + cluster.borrowCaps[PT_pUSDe_16OCT2025 ] = type(uint256).max; // define IRM classes here and assign them to the assets { - // Base=0.00% APY, Kink(90.00%)=7.50% APY Max=40.00% APY - uint256[4] memory irm_USD_1_MEGA_YIELD = [uint256(0), uint256(592877497), uint256(19489392122), uint256(3865470566)]; + // Base=0.00% APY, Kink(90.00%)=8.00% APY Max=15.00% APY + uint256[4] memory irm_USD_1_MEGA_YIELD_OLD = [uint256(0), uint256(630918865), uint256(4633519165), uint256(3865470566)]; + + // Base=5.00% APY, Kink(90.00%)=10.00% APY Max=20.00% APY + uint256[4] memory irm_USD_1_MEGA_YIELD = [uint256(1546098748700445000), uint256(381366399), uint256(6419794564), uint256(3865470566)]; // Base=0% APY, Kink(30%)=12.75% APY Max=848.77% APY uint256[4] memory irm_USD_3_MEGA_YIELD = [uint256(0), uint256(2951312420), uint256(22450463582), uint256(1288490188)]; - // Base=0.00% APY, Kink(85.00%)=7.00% APY Max=40.00% APY - uint256[4] memory irm_eUSDe = [uint256(0), uint256(587285771), uint256(13222240360), uint256(3650722201)]; + // Base=5.00% APY, Kink(90.00%)=10.00% APY Max=15.00% APY + uint256[4] memory irm_USDC_USDT = [uint256(1546098748700445000), uint256(381366399), uint256(3279699693), uint256(3865470566)]; + + // Base=5.00% APY, Kink(90.00%)=10.00% APY Max=40.00% APY + uint256[4] memory irm_eUSDe_rUSD = [uint256(1546098748700445000), uint256(381366399), uint256(17793200339), uint256(3865470566)]; // Base=0% APY, Kink(30%)=2.00% APY Max=80.00% APY uint256[4] memory irm_sUSDe = [uint256(0), uint256(487019827), uint256(5986640502), uint256(1288490188)]; - // Base=0% APY, Kink(90%)=7.00% APY Max=40.00% APY - uint256[4] memory irm_rUSD = [uint256(0), uint256(554658784), uint256(19833360540), uint256(3865470566)]; - // Base=0% APY, Kink(90%)=1.50% APY Max=80.00% APY uint256[4] memory irm_syrupUSDC = [uint256(0), uint256(122055342), uint256(42269044890), uint256(3865470566)]; - cluster.kinkIRMParams[USDC ] = irm_USD_1_MEGA_YIELD; - cluster.kinkIRMParams[USDT ] = irm_USD_1_MEGA_YIELD; + cluster.kinkIRMParams[USDC ] = irm_USDC_USDT; + cluster.kinkIRMParams[USDT ] = irm_USDC_USDT; cluster.kinkIRMParams[PYUSD ] = irm_USD_1_MEGA_YIELD; cluster.kinkIRMParams[rlUSD ] = irm_USD_1_MEGA_YIELD; cluster.kinkIRMParams[wM ] = irm_USD_1_MEGA_YIELD; - cluster.kinkIRMParams[USDS ] = irm_USD_1_MEGA_YIELD; + cluster.kinkIRMParams[USDS ] = irm_USD_1_MEGA_YIELD_OLD; cluster.kinkIRMParams[sUSDS ] = irm_USD_3_MEGA_YIELD; - cluster.kinkIRMParams[DAI ] = irm_USD_1_MEGA_YIELD; + cluster.kinkIRMParams[DAI ] = irm_USD_1_MEGA_YIELD_OLD; cluster.kinkIRMParams[sDAI ] = irm_USD_3_MEGA_YIELD; - cluster.kinkIRMParams[USD0 ] = irm_USD_1_MEGA_YIELD; + cluster.kinkIRMParams[USD0 ] = irm_USD_1_MEGA_YIELD_OLD; cluster.kinkIRMParams[USD0PlusPlus] = irm_USD_3_MEGA_YIELD; cluster.kinkIRMParams[USDe ] = irm_USD_1_MEGA_YIELD; - cluster.kinkIRMParams[eUSDe ] = irm_eUSDe; + cluster.kinkIRMParams[eUSDe ] = irm_eUSDe_rUSD; cluster.kinkIRMParams[sUSDe ] = irm_sUSDe; cluster.kinkIRMParams[USDtb ] = irm_USD_1_MEGA_YIELD; - cluster.kinkIRMParams[rUSD ] = irm_rUSD; + cluster.kinkIRMParams[rUSD ] = irm_eUSDe_rUSD; cluster.kinkIRMParams[syrupUSDC ] = irm_syrupUSDC; cluster.kinkIRMParams[mBASIS ] = irm_USD_3_MEGA_YIELD; } @@ -249,31 +246,40 @@ contract Cluster is ManageCluster { cluster.spreadLTV = 0.02e4; for (uint256 i = 0; i < cluster.vaults.length; ++i) { - cluster.spreadLTVOverride[24][i] = 0.025e4; // PT_sUSDe_31JULY2025 as collateral - cluster.spreadLTVOverride[26][i] = 0.025e4; // PT_eUSDe_14AUG2025 as collateral + cluster.spreadLTVOverride[21][i] = 0.025e4; // PT_sUSDe_31JULY2025 as collateral + cluster.spreadLTVOverride[22][i] = 0.025e4; // PT_sUSDe_25SEP2025 as collateral + cluster.spreadLTVOverride[23][i] = 0.025e4; // PT_eUSDe_14AUG2025 as collateral } cluster.spreadLTVOverride[12][11] = 0.01e4; // eUSDe/USDe cluster.spreadLTVOverride[16][15] = 0.015e4; // srUSD/rUSD - cluster.spreadLTVOverride[22][11] = 0.01e4; // PT_USDe_31JUL2025/USDe - cluster.spreadLTVOverride[22][12] = 0.01e4; // PT_USDe_31JUL2025/eUSDe - cluster.spreadLTVOverride[22][13] = 0.01e4; // PT_USDe_31JUL2025/sUSDe + cluster.spreadLTVOverride[19][11] = 0.01e4; // PT_USDe_31JUL2025/USDe + cluster.spreadLTVOverride[19][12] = 0.01e4; // PT_USDe_31JUL2025/eUSDe + cluster.spreadLTVOverride[19][13] = 0.01e4; // PT_USDe_31JUL2025/sUSDe + + cluster.spreadLTVOverride[20][11] = 0.01e4; // PT_USDe_25SEP2025/USDe + cluster.spreadLTVOverride[20][12] = 0.01e4; // PT_USDe_25SEP2025/eUSDe + cluster.spreadLTVOverride[20][13] = 0.01e4; // PT_USDe_25SEP2025/sUSDe - cluster.spreadLTVOverride[24][11] = 0.01e4; // PT_sUSDe_31JULY2025/USDe - cluster.spreadLTVOverride[24][12] = 0.01e4; // PT_sUSDe_31JULY2025/eUSDe - cluster.spreadLTVOverride[24][13] = 0.01e4; // PT_sUSDe_31JULY2025/sUSDe + cluster.spreadLTVOverride[21][11] = 0.01e4; // PT_sUSDe_31JULY2025/USDe + cluster.spreadLTVOverride[21][12] = 0.01e4; // PT_sUSDe_31JULY2025/eUSDe + cluster.spreadLTVOverride[21][13] = 0.01e4; // PT_sUSDe_31JULY2025/sUSDe + + cluster.spreadLTVOverride[22][11] = 0.01e4; // PT_sUSDe_25SEP2025/USDe + cluster.spreadLTVOverride[22][12] = 0.01e4; // PT_sUSDe_25SEP2025/eUSDe + cluster.spreadLTVOverride[22][13] = 0.01e4; // PT_sUSDe_25SEP2025/sUSDe - cluster.spreadLTVOverride[26][11] = 0.01e4; // PT_eUSDe_14AUG2025/USDe - cluster.spreadLTVOverride[26][12] = 0.01e4; // PT_eUSDe_14AUG2025/eUSDe + cluster.spreadLTVOverride[23][11] = 0.01e4; // PT_eUSDe_14AUG2025/USDe + cluster.spreadLTVOverride[23][12] = 0.01e4; // PT_eUSDe_14AUG2025/eUSDe - cluster.spreadLTVOverride[29][17] = 0.01e4; // PT_syrupUSDC_28AUG2025/syrupUSDC + cluster.spreadLTVOverride[25][17] = 0.01e4; // PT_syrupUSDC_28AUG2025/syrupUSDC - cluster.spreadLTVOverride[30][5] = 0.01e4; // PT_USDS_14AUG2025/USDS - cluster.spreadLTVOverride[30][6] = 0.01e4; // PT_USDS_14AUG2025/sUSDS - cluster.spreadLTVOverride[30][7] = 0.01e4; // PT_USDS_14AUG2025/DAI - cluster.spreadLTVOverride[30][8] = 0.01e4; // PT_USDS_14AUG2025/sDAI + cluster.spreadLTVOverride[26][5] = 0.01e4; // PT_USDS_14AUG2025/USDS + cluster.spreadLTVOverride[26][6] = 0.01e4; // PT_USDS_14AUG2025/sUSDS + cluster.spreadLTVOverride[26][7] = 0.01e4; // PT_USDS_14AUG2025/DAI + cluster.spreadLTVOverride[26][8] = 0.01e4; // PT_USDS_14AUG2025/sDAI for (uint256 i = 0; i < cluster.vaults.length; ++i) { cluster.borrowLTVsOverride[10][i] = 0.84e4; // USD0PlusPlus as collateral @@ -284,47 +290,46 @@ contract Cluster is ManageCluster { // define ltv values here. columns are liability vaults, rows are collateral vaults cluster.ltvs = [ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 - // USDC USDT PYUSD rlUSD wM USDS sUSDS DAI sDAI USD0 USD0++ USDe eUSDe sUSDe USDtb rUSD srUSD syrupUSDC mBASIS mEDGE mMEV PT_USD0PlusPlus_26JUN2025 PT_USDe_31JUL2025 PT_sUSDe_29MAY2025 PT_sUSDe_31JULY2025 PT_eUSDe_29MAY2025 PT_eUSDe_14AUG2025 PT_cUSDO_19JUN2025 PT_cUSDO_20NOV2025 PT_syrupUSDC_28AUG2025 PT_USDS_14AUG2025 - /* 0 USDC */ [uint16(0.00e4), 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.95e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 1 USDT */ [uint16(0.95e4), 0.00e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.95e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 2 PYUSD */ [uint16(0.93e4), 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.930e4, 0.00e4, 0.00e4, 0.93e4, 0.930e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 3 rlUSD */ [uint16(0.95e4), 0.95e4, 0.95e4, 0.00e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 4 wM */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.930e4, 0.00e4, 0.00e4, 0.93e4, 0.930e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 5 USDS */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.930e4, 0.00e4, 0.00e4, 0.93e4, 0.930e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 6 sUSDS */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.930e4, 0.00e4, 0.00e4, 0.93e4, 0.930e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 7 DAI */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.00e4, 0.930e4, 0.00e4, 0.00e4, 0.93e4, 0.930e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 8 sDAI */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.930e4, 0.00e4, 0.00e4, 0.93e4, 0.930e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 9 USD0 */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4, 0.900e4, 0.00e4, 0.00e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 10 USD0PlusPlus */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.900e4, 0.00e4, 0.00e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 11 USDe */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 12 eUSDe */ [uint16(0.88e4), 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.00e4, 0.88e4, 0.00e4, 0.88e4, 0.00e4, 0.940e4, 0.00e4, 0.00e4, 0.88e4, 0.880e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 13 sUSDe */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.900e4, 0.00e4, 0.00e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 14 USDtb */ [uint16(0.95e4), 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 15 rUSD */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 16 srUSD */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.975e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 17 syrupUSDC */ [uint16(0.92e4), 0.92e4, 0.92e4, 0.92e4, 0.92e4, 0.92e4, 0.92e4, 0.92e4, 0.92e4, 0.92e4, 0.00e4, 0.920e4, 0.00e4, 0.00e4, 0.92e4, 0.920e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 18 mBASIS */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.900e4, 0.00e4, 0.00e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 19 mEDGE */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 20 mMEV */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 21 PT_USD0PlusPlus_26JUN2025 */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 22 PT_USDe_31JUL2025 */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.940e4, 0.92e4, 0.92e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 23 PT_sUSDe_29MAY2025 */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 24 PT_sUSDe_31JULY2025 */ [uint16(0.88e4), 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.00e4, 0.925e4, 0.92e4, 0.94e4, 0.88e4, 0.880e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 25 PT_eUSDe_29MAY2025 */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 26 PT_eUSDe_14AUG2025 */ [uint16(0.88e4), 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.00e4, 0.935e4, 0.94e4, 0.00e4, 0.88e4, 0.880e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 27 PT_cUSDO_19JUN2025 */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 28 PT_cUSDO_20NOV2025 */ [uint16(0.88e4), 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.00e4, 0.88e4, 0.00e4, 0.88e4, 0.00e4, 0.880e4, 0.00e4, 0.00e4, 0.00e4, 0.880e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 29 PT_syrupUSDC_28AUG2025 */ [uint16(0.88e4), 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.00e4, 0.880e4, 0.00e4, 0.00e4, 0.88e4, 0.880e4, 0.00e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 30 PT_USDS_14AUG2025 */ [uint16(0.92e4), 0.92e4, 0.92e4, 0.92e4, 0.92e4, 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.92e4, 0.00e4, 0.920e4, 0.00e4, 0.00e4, 0.92e4, 0.920e4, 0.00e4, 0.92e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4] + // USDC USDT PYUSD rlUSD wM USDS sUSDS DAI sDAI USD0 USD0++ USDe eUSDe sUSDe USDtb rUSD srUSD syrupUSDC mBASIS PT_USDe_31JUL2025 PT_USDe_25SEP2025 PT_sUSDe_31JULY2025 PT_sUSDe_25SEP2025 PT_eUSDe_14AUG2025 PT_cUSDO_20NOV2025 PT_syrupUSDC_28AUG2025 PT_USDS_14AUG2025 PT_tUSDe_25SEP2025 PT_pUSDe_16OCT2025 + /* 0 USDC */ [uint16(0.00e4), 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.95e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 1 USDT */ [uint16(0.95e4), 0.00e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.95e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 2 PYUSD */ [uint16(0.93e4), 0.93e4, 0.00e4, 0.93e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.930e4, 0.00e4, 0.00e4, 0.93e4, 0.930e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 3 rlUSD */ [uint16(0.95e4), 0.95e4, 0.95e4, 0.00e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 4 wM */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.930e4, 0.00e4, 0.00e4, 0.93e4, 0.930e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 5 USDS */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 6 sUSDS */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 7 DAI */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 8 sDAI */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 9 USD0 */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 10 USD0PlusPlus */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.900e4, 0.00e4, 0.00e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 11 USDe */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 12 eUSDe */ [uint16(0.88e4), 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.940e4, 0.00e4, 0.00e4, 0.88e4, 0.880e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 13 sUSDe */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.900e4, 0.00e4, 0.00e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 14 USDtb */ [uint16(0.95e4), 0.95e4, 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.950e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 15 rUSD */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 16 srUSD */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.975e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 17 syrupUSDC */ [uint16(0.92e4), 0.92e4, 0.92e4, 0.92e4, 0.92e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.920e4, 0.00e4, 0.00e4, 0.92e4, 0.920e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 18 mBASIS */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 19 PT_USDe_31JUL2025 */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 20 PT_USDe_25SEP2025 */ [uint16(0.90e4), 0.90e4, 0.90e4, 0.90e4, 0.90e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.940e4, 0.92e4, 0.92e4, 0.90e4, 0.900e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 21 PT_sUSDe_31JULY2025 */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 22 PT_sUSDe_25SEP2025 */ [uint16(0.88e4), 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.925e4, 0.92e4, 0.94e4, 0.88e4, 0.880e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 23 PT_eUSDe_14AUG2025 */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 24 PT_cUSDO_20NOV2025 */ [uint16(0.88e4), 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.880e4, 0.00e4, 0.00e4, 0.00e4, 0.880e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 25 PT_syrupUSDC_28AUG2025 */ [uint16(0.88e4), 0.88e4, 0.88e4, 0.88e4, 0.88e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.880e4, 0.00e4, 0.00e4, 0.88e4, 0.880e4, 0.00e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 26 PT_USDS_14AUG2025 */ [uint16(0.00e4), 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.000e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 27 PT_tUSDe_25SEP2025 */ [uint16(0.87e4), 0.87e4, 0.87e4, 0.87e4, 0.87e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.925e4, 0.92e4, 0.00e4, 0.87e4, 0.870e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 28 PT_pUSDe_16OCT2025 */ [uint16(0.87e4), 0.87e4, 0.87e4, 0.87e4, 0.87e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.925e4, 0.92e4, 0.00e4, 0.87e4, 0.870e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4] ]; // define external ltvs here. columns are liability vaults, rows are collateral vaults. // double check the order of collaterals against the order of externalVaults in the addresses file cluster.externalLTVs = [ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 - // USDC USDT PYUSD rlUSD wM USDS sUSDS DAI sDAI USD0 USD0++ USDe eUSDe sUSDe USDtb rUSD srUSD syrupUSDC mBASIS mEDGE mMEV PT_USD0PlusPlus_26JUN2025 PT_sUSDe_29MAY2025 PT_USDe_31JUL2025 PT_sUSDe_31JULY2025 PT_eUSDe_29MAY2025 PT_eUSDe_14AUG2025 PT_cUSDO_19JUN2025 PT_cUSDO_20NOV2025 PT_syrupUSDC_28AUG2025 PT_USDS_14AUG2025 - /* 0 Prime USDC */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], - /* 1 Prime USDT */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4] + // USDC USDT PYUSD rlUSD wM USDS sUSDS DAI sDAI USD0 USD0++ USDe eUSDe sUSDe USDtb rUSD srUSD syrupUSDC mBASIS PT_USDe_31JUL2025 PT_USDe_25SEP2025 PT_sUSDe_31JULY2025 PT_sUSDe_25SEP2025 PT_eUSDe_14AUG2025 PT_cUSDO_20NOV2025 PT_syrupUSDC_28AUG2025 PT_USDS_14AUG2025 PT_tUSDe_25SEP2025 PT_pUSDe_16OCT2025 + /* 0 Prime USDC */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 1 Prime USDT */ [uint16(0.93e4), 0.93e4, 0.93e4, 0.93e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.93e4, 0.00e4, 0.93e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4], + /* 2 RWA sBUIDL */ [uint16(0.95e4), 0.95e4, 0.95e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.95e4, 0.00e4, 0.00e4, 0.95e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4, 0.00e4] ]; } diff --git a/script/production/mainnet/governedPerspectiveVaults/EulerEarnGovernedPerspectiveVaults.csv b/script/production/mainnet/governedPerspectiveVaults/EulerEarnGovernedPerspectiveVaults.csv index 99522e0a..b3e96371 100644 --- a/script/production/mainnet/governedPerspectiveVaults/EulerEarnGovernedPerspectiveVaults.csv +++ b/script/production/mainnet/governedPerspectiveVaults/EulerEarnGovernedPerspectiveVaults.csv @@ -1,3 +1,2 @@ Vault,Governor,Whitelist -0x4E1C52199d2A1fBE02B0Cb436BE97B0BC0D8e389,Euler,Yes -0x157f3F5f5A66f50D5E3581A35F70ffDFd5237fdA,Euler,Yes \ No newline at end of file +0x3B4802FDb0E5d74aA37d58FD77d63e93d4f9A4AF,Euler USDC,Yes \ No newline at end of file diff --git a/script/production/mainnet/governedPerspectiveVaults/GovernedPerspectiveVaults.csv b/script/production/mainnet/governedPerspectiveVaults/GovernedPerspectiveVaults.csv index 2c325b45..2a9a5353 100644 --- a/script/production/mainnet/governedPerspectiveVaults/GovernedPerspectiveVaults.csv +++ b/script/production/mainnet/governedPerspectiveVaults/GovernedPerspectiveVaults.csv @@ -24,6 +24,10 @@ Vault,Governor,Whitelist 0xA28C23a459fF8773EB4dBe0e7250d93F79F1Fe2B,Euler Prime,Yes 0x328646cdfBaD730432620d845B8F5A2f7D786C01,Euler Prime,Yes 0xc2d36F41841B420937643dcccbEa8163D4F59B6c,Euler Prime,Yes +0x22eed7C25A35D40255cd80d3B67A2F8742f94443,Euler Prime,Yes +0x6bE9e82B25987Ce66AcD89130fEe494EDd0473AE,Euler Prime,Yes +0xee944C7Dd107617550EC11AFCF652e14E7670A37,Euler Prime,Yes +0x5A96128c18018a2cEf539f46Bbed037DAD3cAAe8,Euler Prime,Yes 0xe0a80d35bB6618CBA260120b279d357978c42BCE,Euler Yield,Yes 0x7c280DBDEf569e96c7919251bD2B0edF0734C5A8,Euler Yield,Yes 0x519Ea32be221E2EBb066d4781359a1c96579840F,Euler Yield,No @@ -63,6 +67,10 @@ Vault,Governor,Whitelist 0x0934554feefa7e264C349cDe626933b908166635,Euler Yield,Yes 0xaabc07A47D2a63a9b06A7924a0780c2F3cAE7bf9,Euler Yield,Yes 0x43356281a62dc8712C7186Ca02BA3aD906B6181D,Euler Yield,Yes +0xb53b4B2590457bE63E1DCdAffa6a18ECd44D96D2,Euler Yield,Yes +0xA9902f9210059171C52b2721424E00f48821dcf3,Euler Yield,Yes +0xbF34Cf6F1C098231E16D7Be38a2aE13EfE9b92d3,Euler Yield,Yes +0x2f94Bbe20ECa1e3f9332aA93A90920a0a5be0728,Euler Yield,Yes 0x959Ae4dD74fD525b33Ff0ff776B4b352abd48322,Euler Repo,No 0xDF78489C3cFC738194afE34fb3F379c0A3E0c5Db,Euler Repo,No 0xc943c1CDD7b3Fbb6A77f571698406b418C902f0c,Euler Repo,No @@ -78,27 +86,37 @@ Vault,Governor,Whitelist 0xabBe766f216f689818C3A1f98647cE4E41495325,Euler RWA,Yes 0x155d4A34938dcB27486f5Bbf6a19d19D0ef0DD8A,Euler RWA,Yes 0xC51e90b48FD7fBfF316502b85A71e0EBb1ee5238,Euler RWA,Yes +0x74034eb8d5B2E480825263A975E4CF82A081c959,EUL Swap,Yes 0xdc1aeF6cF0F13267281a0D3547D205eA32287e49,Euler Frontier Renzo,Yes 0x0c01F00e419977CF452e78AaE35ffB95C47d9534,Euler Frontier Renzo,Yes 0x98281466aBcF48eAAD8c6E22dEdD18A3426A93b4,Euler Frontier mMEV,Yes +0x75E695C60aF0780F8c9FA79e37946a02f4481c09,Euler Frontier mMEV,Yes 0x3F7CcadEd39Fd9D06Eb0498ABEb7EAAB569E79Ad,Euler Frontier mMEV,Yes 0x819662Ab6Fe32B52100fa32aE3e0e8b36B4C5638,Euler Frontier mMEV,Yes +0xdc685C0b34eDd19f702a8ad4cD4d8279F6452AC8,Euler Frontier mMEV,Yes 0x09136DAC538B54994170a6905507a74562A80ed3,Euler Frontier mEDGE,Yes +0x122e9eA082D8c060Bb1a3476aa18B9E739fBbAAf,Euler Frontier mEDGE,Yes 0xD53f83c7CA5189007C09b5D867a8116bC0540724,Euler Frontier mEDGE,Yes 0x94EdbB8F7543593FF1B8D2871eC4730B59c97888,Euler Frontier mEDGE,Yes +0x561fF99A243868fdf755705b1B83e6C4E8B8B0dF,Euler Frontier mEDGE,Yes 0xF4Bc4239eDca81ed0d305701CB18A5Fd82cd06Ca,Euler Frontier Level,Yes +0x3bFA6657982A9Ada1388CF798F3f211711Daf4E5,Euler Frontier Level,Yes 0xfc6f3A2Badb53973F69449Da690Cfef84dc4a359,Euler Frontier Level,Yes 0x1e0b68A83Ef062CDE687351C472cFd0E9300A06d,Euler Frontier Level,Yes 0xF2ec2d8fE1351bAFF31643855C0f4D1E63Bd1ce4,Euler Frontier Level,Yes 0x889b0ab73A262759e1Da530eA027268Fd9C2B35f,Euler Frontier Level,Yes 0x3573A84Bee11D49A1CbCe2b291538dE7a7dD81c6,Euler Frontier Falcon,Yes +0xbFdc482616787b420BC6C710212fE3167E7198e9,Euler Frontier Falcon,Yes 0x412D0E31790D77b6e7a7872a9fd6967B6E640229,Euler Frontier Falcon,Yes 0x2F849ba554C1ea2eDe9C240Bbe9d247dd6eC8A6B,Euler Frontier Falcon,Yes 0xE415952f5ee06f8A548F4f7D5bE18FBf144b4E4D,Euler Frontier Falcon,Yes +0xa7A064f56FbcA60cBeD47eD3e13C4B945DEf7eC3,Euler Frontier Falcon,Yes 0x81f8ac1a4756BfE9D7ce138C0C3baD2Cb5E8a582,Euler Frontier sDOLA,Yes +0x77710edfeDfB7e9186CBA71b258C75ea2AED5f84,Euler Frontier sDOLA,Yes 0xE668c3F45D126A72cf696Ff46054918Cf1337786,Euler Frontier sDOLA,Yes 0x3152EC91ec776f918Cc2090F58319A5a614536e0,Euler Frontier sDOLA,Yes 0x481D4909D7ca2eb27c4975f08dCE07DBeF0d3Fa7,Euler Frontier Yala,Yes +0x2dF9753E62f46B299F59E632bd18EdfE4970922e,Euler Frontier Yala,Yes 0x1F46186AF85A967416b17380800c69860B7C516F,Euler Frontier Yala,Yes 0x0F93f35c0664A6a8231ccAe7E22f652c9c075b32,Euler Frontier Yala,Yes 0x87c414825aB3d1E9bdC773e9B1fD968822c9CF51,Euler Frontier hgETH,Yes @@ -106,6 +124,30 @@ Vault,Governor,Whitelist 0x18337806b02b02099209b05589E6db85acD4345C,Euler Frontier hgETH,Yes 0xc2c4aBae84fbb5b7bAAB52301A924b1F986C66bd,Euler Frontier pufETH,Yes 0x46BC453666BA11b4b08B0804E49A9D797546ee7D,Euler Frontier pufETH,Yes +0xa94F9CE821C7bD57cc12991CB46ca19f5789278F,Euler Frontier Pareto,Yes +0xF2ef3e32FCF4BfE21266727281B73F95Cd520411,Euler Frontier Pareto,Yes +0xa3e0943d0196F76db58d3549C9a7528Ef4ac335F,Euler Frontier Pareto,Yes +0x15A60a5300c1D9179d4c0e2B49bac6146794Ae1F,Euler Frontier Reservoir,Yes +0x607589437A3b52f536706642a9b7c70192C37940,Euler Frontier Reservoir,Yes +0xACD489AdEC33cd7c46FC448cf77376f1EaF5f3ab,Euler Frontier Reservoir,Yes +0xb5c0EC2b53b87720f2D99B75c01C6d4Da0e724F8,Euler Frontier Reservoir,Yes +0x58CD6Ae0Bd452d3219366C7ddD37cA1A12d2ff59,Euler Frontier Spark,Yes +0x7fD46A66b5Ed6dC395603678cf9BE8846e01Fe25,Euler Frontier Spark,Yes +0x13a2322907cea4CE62525476f9dAc191f0B590Db,Euler Frontier Spark,Yes +0x00011d9A1EB3d7278b8DF2391e2E32f6f9bcF293,Euler Frontier Spark,Yes +0xc727069c0eb261Be642272fe3848518192683fFc,Euler Frontier YieldFi,Yes +0xd90f695D98b6E1fAA7BA516A777fF12cc3C111a4,Euler Frontier YieldFi,Yes +0x3eD8f77Ca6FD9e5c6DBBcC9696BF93F30C3A2BA5,Euler Frontier YieldFi,Yes +0xb76e9E04d4356756c9b8E002Cc4dabFA4e02BD93,Euler Frontier YieldFi,Yes +0x3C75C170671acb394804DfAf63e4F9891C121625,Euler Frontier Hyperwave,Yes +0x22cC732cbca457F6811295bCE75B01822544bA52,Euler Frontier Hyperwave,Yes +0x4f36Bebf5dDb4b804F9C72644aEe82BAd165BFfc,Euler Frontier Hyperwave,Yes +0x9c6bDF412723ADF2798B163638083783506B26e3,Euler Frontier Hyperwave,Yes +0x53AfE3343f322c4189Ab69E0D048efd154259419,Euler Frontier Strata,Yes +0x09FcE883cC16894274802c01e3b9cD90EAE4e43d,Euler Frontier Strata,Yes +0x6331D36C27D967c4261D59a8f80d58d03089810A,Euler Frontier Strata,Yes +0xBd360BB80E6CBe86e533B672Df6BFc054602ADBD,Euler Frontier Strata,Yes +0xCfC6a55Aa72DCF3755A515aE8B82552028b63D2A,Euler Frontier Strata,Yes 0x315F93a074D0948E4D068e98a34092750ea8A38C,Apostro Lido Ecosystem,Yes 0xf9a23b059858CdD0e3ED0DDE89864BB82B88aa19,Apostro Lido Ecosystem,Yes 0xBe4089616039eC3F7361B7058d92a90246ee86e0,Dinero,No @@ -127,7 +169,7 @@ Vault,Governor,Whitelist 0x25C538cc5c5B4cDdf9a9A656f90d2d8129E841B2,Alterscope Bedrock,Yes 0xD1552d878FE4869539ba4D03D207B54913a5C273,Alterscope Bedrock,Yes 0xFc323C1727853872A85098EA89a6882853B708dd,Alterscope Bedrock,Yes -0xfC67343ac17B158deb69de67Ba8A2eD7C47F0C74,Alterscope Bedrock,Yes +0xfC67343ac17B158deb69de67Ba8A2eD7C47F0C74,Alterscope Bedrock,No 0xd6506dB835B465d5d823add8667362d7b86cFe5F,Alterscope Bedrock,Yes 0x5a0064007ddDEa2C8d6547A7B1E862c619500994,Alterscope Bedrock,Yes 0x41722452C0348501825C494ec6C1579e9c32D277,Alterscope Bedrock,Yes @@ -149,6 +191,8 @@ Vault,Governor,Whitelist 0x45c3B59d53e2e148Aaa6a857521059676D5c0489,Alterscope LRT,Yes 0x05755D78caD24417c42960b93D3Bf821a92e4d82,Alterscope LRT,Yes 0x91Fa3167591Fe29071F265d076B64c22A89Ae9AD,Alterscope LRT,Yes +0x5CD9876B7F0fd134F442F4e6c8A566F290cB7580,Alterscope LRT,Yes +0xfc6600B186d5B8B2fe59667Efc0A479a7AC3f1B4,Alterscope LRT,Yes 0x6b6976aA97CD2473B388fA9b9eEb8Cca4F5a77a4,MEV Capital WETH Cluster,Yes 0x6C37d34a895456AA29CABe0caCB60FC56309C7ac,MEV Capital WETH Cluster,Yes 0x9426C7a40d5C9DD709cbc2894a7E6481f265B6Bb,MEV Capital WETH Cluster,Yes @@ -234,4 +278,6 @@ Vault,Governor,Whitelist 0x9ee58f0618d2bf130b73f2d843c45c69548b981b,K3 Liquity Hub,Yes 0xc6137bc1378c2396051e06417704d31615f77cb9,K3 Liquity Hub,Yes 0xc1c51c5c9efaf0c485aa1097ae9690b5e102975a,K3 Liquity Hub,Yes -0xec91b109817b20d4ebd364a181666327194763f0,K3 Liquity Hub,Yes \ No newline at end of file +0xec91b109817b20d4ebd364a181666327194763f0,K3 Liquity Hub,Yes +0x5e4CfCe564d741373bD0078CB256E94696354C46,K3 Liquity Hub,Yes +0x5BcA378719Ad01BB8e490d09e2326EDfEe66b954,K3 Liquity Hub,Yes \ No newline at end of file diff --git a/script/production/sonic/governedPerspectiveVaults/GovernedPerspectiveVaults.csv b/script/production/sonic/governedPerspectiveVaults/GovernedPerspectiveVaults.csv index 4affd9af..33e15736 100644 --- a/script/production/sonic/governedPerspectiveVaults/GovernedPerspectiveVaults.csv +++ b/script/production/sonic/governedPerspectiveVaults/GovernedPerspectiveVaults.csv @@ -20,6 +20,9 @@ Vault,Governor,Whitelist 0x6e14A20334724a194D2f8B38162522CAD202b986,MEV Capital,Yes 0x6F11663766bB213003cD74EB09ff4c67145023c5,MEV Capital,Yes 0xC37fa1c70D77bdEd373C551a92bAbcee44a9d04E,MEV Capital,Yes +0x8D024593d781B1C86EcD5d0f899d10C5E9de7069,MEV Capital,Yes +0x2A377470DcF0e00F6DEd484DDf82df65F0Fb50af,MEV Capital,Yes +0xB6a53021E7A40ea20DF1e1991B0C89432073386E,MEV Capital,Yes 0x90a804D316A06E00755444D56b9eF52e5C4F4D73,MEV Capital Beets,Yes 0x6832F3090867449c058e1e3088E552E12AB18F9E,MEV Capital Beets,Yes 0xb936137169D777fcB8B7Cf02329620B78FCcEC0A,MEV Capital Beets,Yes diff --git a/script/production/tac/governedPerspectiveVaults/GovernedPerspectiveVaults.csv b/script/production/tac/governedPerspectiveVaults/GovernedPerspectiveVaults.csv new file mode 100644 index 00000000..d01498db --- /dev/null +++ b/script/production/tac/governedPerspectiveVaults/GovernedPerspectiveVaults.csv @@ -0,0 +1,25 @@ +Vault,Governor,Whitelist +0xF8B65DebBE84f52E7256AEdd251d067440E75023,Test,No +0xB17e948876d623e56d909717157664CE000f0a5C,Test,No +0x7545F4ee5d8D234E6e7e704C8e033D9740251BA6,Test,No +0x27324c0d445f94550b53936dBAB7fD168634f192,Re7,Yes +0xc7F25f1c8FDB86DE3d14152034de4EB8B71eEC78,Re7,Yes +0x4ac2478eb1DDf574b0ffF297a25BB496af1fA207,Re7,Yes +0x2eF66758705426e7BF598669AEf23eE9b9CC3088,Re7,Yes +0x15794A8e1708511DABeC3d356aDDbE7128E90D8F,Re7,Yes +0xE2E106a9Ec7bc7F5dcDf5a20Ea007b833cCf4f1f,Re7,Yes +0x0Fa94ABEC53c176f9bf1Ae6c871a1214D8aECec8,Re7,Yes +0xa88869168951a3eb12484814e7a6ea3f0ac70e69,Re7,Yes +0xdD6EaEf38F94d4724124cEc14c819818714537Ff,Edge Capital,Yes +0x2c8a93667D8909FA8F0c24F2c571C9163D3fB77A,Edge Capital,Yes +0x72D0e285166B0dDe84eE247c16e45979725D1399,Edge Capital,Yes +0x994a7766a0e658098cA01A1ADf114abD29e5629e,Edge Capital,Yes +0x73475c15FE4Cb39AD0c58Cb520E7A5771Ae8fC44,Edge Capital,Yes +0x522e6437B80B11C10AaFDB321c3610B85127E4CD,Edge Capital,Yes +0x41068B2c61d535a370E39415E090eC2100B57934,Edge Capital,Yes +0xf055eaa0802Fd2A1A6320D2308925831092A534C,Edge Capital,Yes +0xCc69e827EA1eB78dA3eD1543256d3916B4078620,Edge Capital,Yes +0xd5fFE1231F5610C68dD67eD3b870541D0A63aF50,Edge Capital,Yes +0xE82A5eD2d6E0423317F2a7FdB3B21215411791e0,Edge Capital,Yes +0xcAA9c74f87D31bC280AF5666BdC868DEe2064fE8,Edge Capital,Yes +0x921209493da603056De9B9a46eCE14b996a75088,Edge Capital,Yes diff --git a/script/production/unichain/clusters/UnichainCluster.json b/script/production/unichain/clusters/UnichainCluster.json index e02501fd..e124029e 100644 --- a/script/production/unichain/clusters/UnichainCluster.json +++ b/script/production/unichain/clusters/UnichainCluster.json @@ -1,9 +1,9 @@ { "externalVaults": [], "irms": [ - "0x9A8639511232aBd124140e770341DE4ADd705Bb0", - "0x9A8639511232aBd124140e770341DE4ADd705Bb0", - "0x085803CcEc8b2494c0bff225B548A628E5fA27fc", + "0xbdcd0b70DC380f5AB48398aF14bfe03CbCD375D3", + "0xbdcd0b70DC380f5AB48398aF14bfe03CbCD375D3", + "0x39977CbE15663Ed2D292b9A3276DabB59f2a534c", "0x0C4D0F29ECf4C6f712dE44a868E3f033fB2a3967", "0xcA59581838b0728e6931403168D972dc74463AdA", "0xdf32230f0E506D26A4F9A673595b2bA4835078da", diff --git a/script/production/unichain/clusters/UnichainCluster.s.sol b/script/production/unichain/clusters/UnichainCluster.s.sol index aa52cf6b..0caf2b76 100644 --- a/script/production/unichain/clusters/UnichainCluster.s.sol +++ b/script/production/unichain/clusters/UnichainCluster.s.sol @@ -73,36 +73,36 @@ contract Cluster is ManageCluster { cluster.oracleProviders[UNI ] = "0x7e262cd6226328aaf4ea5c993a952e18dd633bc8"; // define supply caps here. 0 means no supply can occur, type(uint256).max means no cap defined hence max amount - cluster.supplyCaps[USDC ] = 100_000_000; + cluster.supplyCaps[USDC ] = 150_000_000; cluster.supplyCaps[USDT0 ] = 100_000_000; - cluster.supplyCaps[sUSDC ] = 40_000_000; - cluster.supplyCaps[WETH ] = 20_000; - cluster.supplyCaps[wstETH] = 3_000; - cluster.supplyCaps[weETH ] = 30_000; - cluster.supplyCaps[rsETH ] = 2_000; - cluster.supplyCaps[ezETH ] = 2_000; + cluster.supplyCaps[sUSDC ] = 80_000_000; + cluster.supplyCaps[WETH ] = 15_000; + cluster.supplyCaps[wstETH] = 1_130; + cluster.supplyCaps[weETH ] = 22_500; + cluster.supplyCaps[rsETH ] = 1_500; + cluster.supplyCaps[ezETH ] = 1_500; cluster.supplyCaps[WBTC ] = 100; - cluster.supplyCaps[UNI ] = 500_000; + cluster.supplyCaps[UNI ] = 250_000; // define borrow caps here. 0 means no borrow can occur, type(uint256).max means no cap defined hence max amount - cluster.borrowCaps[USDC ] = 90_000_000; + cluster.borrowCaps[USDC ] = 135_000_000; cluster.borrowCaps[USDT0 ] = 90_000_000; - cluster.borrowCaps[sUSDC ] = 32_000_000; - cluster.borrowCaps[WETH ] = 18_000; - cluster.borrowCaps[wstETH] = 750; - cluster.borrowCaps[weETH ] = 12_000; - cluster.borrowCaps[rsETH ] = 500; - cluster.borrowCaps[ezETH ] = 500; + cluster.borrowCaps[sUSDC ] = 64_000_000; + cluster.borrowCaps[WETH ] = 13_500; + cluster.borrowCaps[wstETH] = 290; + cluster.borrowCaps[weETH ] = 9_000; + cluster.borrowCaps[rsETH ] = 375; + cluster.borrowCaps[ezETH ] = 375; cluster.borrowCaps[WBTC ] = 90; - cluster.borrowCaps[UNI ] = 400_000; + cluster.borrowCaps[UNI ] = 200_000; // define IRM classes here and assign them to the assets { - // Base=0.00% APY, Kink(90.00%)=6.00% APY Max=40.00% APY - uint256[4] memory irmUSD = [uint256(0), uint256(477682641), uint256(20526145828), uint256(3865470566)]; + // Base=0.00% APY, Kink(90.00%)=6.50% APY Max=40.00% APY + uint256[4] memory irmUSD = [uint256(0), uint256(516261061), uint256(20178940043), uint256(3865470566)]; - // Base=0.00% APY, Kink(80.00%)=1.50% APY Max=40.00% APY - uint256[4] memory irmSUSDC= [uint256(0), uint256(137312259), uint256(11863395757), uint256(3435973836)]; + // Base=0.00% APY, Kink(80.00%)=2.00% APY Max=40.00% APY + uint256[4] memory irmSUSDC= [uint256(0), uint256(182632435), uint256(11682115056), uint256(3435973836)]; // Base=0.00% APY, Kink(90.00%)=2.70% APY Max=40.00% APY uint256[4] memory irmWETH = [uint256(0), uint256(218407859), uint256(22859618857), uint256(3865470566)]; diff --git a/script/production/unichain/clusters/UnichainLSTCluster.s.sol b/script/production/unichain/clusters/UnichainLSTCluster.s.sol index 2a1ef6d4..13798f18 100644 --- a/script/production/unichain/clusters/UnichainLSTCluster.s.sol +++ b/script/production/unichain/clusters/UnichainLSTCluster.s.sol @@ -60,16 +60,16 @@ contract Cluster is ManageCluster { cluster.oracleProviders[ezETH ] = "0x255bee201d2526bbf2753df6a6057f23431a3e1c"; // define supply caps here. 0 means no supply can occur, type(uint256).max means no cap defined hence max amount - cluster.supplyCaps[WETH ] = 50_000; - cluster.supplyCaps[wstETH] = 20_000; - cluster.supplyCaps[rsETH ] = 10_000; - cluster.supplyCaps[ezETH ] = 10_000; + cluster.supplyCaps[WETH ] = 37_500; + cluster.supplyCaps[wstETH] = 15_000; + cluster.supplyCaps[rsETH ] = 7_500; + cluster.supplyCaps[ezETH ] = 7_500; // define borrow caps here. 0 means no borrow can occur, type(uint256).max means no cap defined hence max amount - cluster.borrowCaps[WETH ] = 45_000; - cluster.borrowCaps[wstETH] = 18_000; - cluster.borrowCaps[rsETH ] = 9_000; - cluster.borrowCaps[ezETH ] = 9_000; + cluster.borrowCaps[WETH ] = 33_000; + cluster.borrowCaps[wstETH] = 13_500; + cluster.borrowCaps[rsETH ] = 6_750; + cluster.borrowCaps[ezETH ] = 6_750; // define IRM classes here and assign them to the assets { diff --git a/script/production/unichain/governedPerspectiveVaults/GovernedPerspectiveVaults.csv b/script/production/unichain/governedPerspectiveVaults/GovernedPerspectiveVaults.csv index 1b0c48d5..2de181c7 100644 --- a/script/production/unichain/governedPerspectiveVaults/GovernedPerspectiveVaults.csv +++ b/script/production/unichain/governedPerspectiveVaults/GovernedPerspectiveVaults.csv @@ -13,4 +13,6 @@ Vault,Governor,Whitelist 0x6Bc1f97f96Dd6834A86aCf412B77C9F464419436,Euler LST,Yes 0xCF28A176021e6906C359d1777041245d9Fda076D,Euler LST,Yes 0xe6806beA4eCDE065bB757c35032f2c625848D8e8,Euler LST,Yes -0x25e2ef0f957B61cdd26BBE954AFD5806A9DaDe49,Euler LST,Yes \ No newline at end of file +0x25e2ef0f957B61cdd26BBE954AFD5806A9DaDe49,Euler LST,Yes +0x218c9e961fC5f6c8280bA160365FAbe8A53Ec6E5,AlphaGrowth,Yes +0x5ADAde21c703912547BFc8952fe1B52f09437E2A,AlphaGrowth,Yes \ No newline at end of file diff --git a/script/utils/ClusterDump.s.sol b/script/utils/ClusterDump.s.sol index e90e3a3b..e617627e 100644 --- a/script/utils/ClusterDump.s.sol +++ b/script/utils/ClusterDump.s.sol @@ -27,7 +27,9 @@ contract ClusterDump is ScriptUtils { coreAddresses.eVaultFactory, peripheryAddresses.oracleAdapterRegistry, peripheryAddresses.kinkIRMFactory, - peripheryAddresses.adaptiveCurveIRMFactory + peripheryAddresses.adaptiveCurveIRMFactory, + peripheryAddresses.kinkyIRMFactory, + peripheryAddresses.fixedCyclicalBinaryIRMFactory ); address vaultLens = lenses[4]; diff --git a/script/utils/ExecuteTimelockTx.s.sol b/script/utils/ExecuteTimelockTx.s.sol index 84f21e68..4e5e945e 100644 --- a/script/utils/ExecuteTimelockTx.s.sol +++ b/script/utils/ExecuteTimelockTx.s.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import {TimelockController} from "openzeppelin-contracts/governance/TimelockController.sol"; import {ScriptExtended} from "../utils/ScriptExtended.s.sol"; -import {Vm} from "../utils/ScriptUtils.s.sol"; +import {Vm, console} from "../utils/ScriptUtils.s.sol"; contract ExecuteTimelockTx is ScriptExtended { bytes32[] topic = new bytes32[](1); @@ -28,9 +28,11 @@ contract ExecuteTimelockTx is ScriptExtended { "ExecuteTimelockTx: Timelock transaction id not ready" ); - uint256 toBlock = block.number; + uint256 toBlock = getToBlock(); uint256 intervals; + if (toBlock == 0) toBlock = block.number; + while (intervals < 100 && !TimelockController(timelock).isOperationDone(timelockId)) { Vm.EthGetLogs[] memory ethLogs = vm.eth_getLogs(toBlock - 1e4, toBlock, timelock, topic); diff --git a/script/utils/SafeUtils.s.sol b/script/utils/SafeUtils.s.sol index 045802b0..9c4fbb56 100644 --- a/script/utils/SafeUtils.s.sol +++ b/script/utils/SafeUtils.s.sol @@ -234,7 +234,8 @@ contract SafeUtil is ScriptExtended { if ( block.chainid == 1 || block.chainid == 10 || block.chainid == 100 || block.chainid == 130 || block.chainid == 137 || block.chainid == 146 || block.chainid == 42161 || block.chainid == 43114 - || block.chainid == 480 || block.chainid == 56 || block.chainid == 57073 || block.chainid == 8453 + || block.chainid == 480 || block.chainid == 56 || block.chainid == 57073 || block.chainid == 59144 + || block.chainid == 8453 ) { return "https://safe-client.safe.global/"; } else if (block.chainid == 1923) { @@ -412,9 +413,8 @@ contract SafeTransaction is SafeUtil { (bool success, bytes memory result) = transaction.to.call{value: transaction.value}(transaction.data); require(success, string(result)); } else { - MultisendMock multisendMock = new MultisendMock(transaction.safe); - (bool success, bytes memory result) = - address(multisendMock).call{value: transaction.value}(transaction.data); + address multisendMock = address(new MultisendMock(transaction.safe)); + (bool success, bytes memory result) = multisendMock.call{value: transaction.value}(transaction.data); require(success, string(result)); } } @@ -536,20 +536,24 @@ contract SafeMultisendBuilder is SafeUtil { } function executeMultisend(address safe, uint256 safeNonce) public { + executeMultisend(safe, safeNonce, true); + } + + function executeMultisend(address safe, uint256 safeNonce, bool isSimulation) public { if (multisendItems.length == 0) return; console.log("\nExecuting the multicall via Safe (%s)", safe); - _simulateMultisend(safe); - SafeTransaction transaction = new SafeTransaction(); + if (!isSimulation) transaction.setSimulationOff(); + _dumpMultisendBatchBuilderFile( safe, string.concat("SafeBatchBuilder_", vm.toString(safeNonce), "_", vm.toString(safe), ".json") ); transaction.create( - false, safe, _getMultisendAddress(block.chainid), _getMultisendValue(), _getMultisendCalldata(), safeNonce + false, safe, _getMultisendAddress(block.chainid), _getMultisendValue(), _getMultisendCalldata(), safeNonce++ ); delete multisendItems; diff --git a/script/utils/ScriptExtended.s.sol b/script/utils/ScriptExtended.s.sol index 47c771dd..b3057e3c 100644 --- a/script/utils/ScriptExtended.s.sol +++ b/script/utils/ScriptExtended.s.sol @@ -239,6 +239,42 @@ abstract contract ScriptExtended is Script { || _strEq(vm.envOr("no_stub_oracle", string("")), "--no-stub-oracle"); } + function getSkipOFTHubChainConfig() internal view returns (bool) { + return _strEq(vm.envOr("skip_oft_hub_chain_config", string("")), "--skip-oft-hub-chain-config"); + } + + function getCheckPhasedOutVaults() internal view returns (bool) { + return _strEq(vm.envOr("check_phased_out_vaults", string("")), "--check-phased-out-vaults"); + } + + function getFromBlock() internal view returns (uint256) { + return vm.envOr("from_block", uint256(0)); + } + + function getToBlock() internal view returns (uint256) { + return vm.envOr("to_block", uint256(0)); + } + + function getSourceWallet() internal view returns (address) { + return vm.envOr("source_wallet", address(0)); + } + + function getDestinationWallet() internal view returns (address) { + return vm.envOr("destination_wallet", address(0)); + } + + function getSourceAccountId() internal view returns (uint8) { + return uint8(vm.envOr("source_account_id", uint256(0))); + } + + function getDestinationAccountId() internal view returns (uint8) { + return uint8(vm.envOr("destination_account_id", uint256(0))); + } + + function getPath() internal view returns (string memory) { + return vm.envOr("path", string("")); + } + function getConfigAddress(string memory key) internal view returns (address) { return getConfigAddress(key, block.chainid); } diff --git a/script/utils/ScriptUtils.s.sol b/script/utils/ScriptUtils.s.sol index c10e6d3e..4863547c 100644 --- a/script/utils/ScriptUtils.s.sol +++ b/script/utils/ScriptUtils.s.sol @@ -71,6 +71,7 @@ abstract contract PeripheryAddressesLib is ScriptExtended { address externalVaultRegistry; address kinkIRMFactory; address kinkyIRMFactory; + address fixedCyclicalBinaryIRMFactory; address adaptiveCurveIRMFactory; address irmRegistry; address swapper; @@ -88,6 +89,7 @@ abstract contract PeripheryAddressesLib is ScriptExtended { address termsOfUseSigner; address governorAccessControlEmergencyFactory; address capRiskStewardFactory; + address eulerEarnPublicAllocator; } function serializePeripheryAddresses(PeripheryAddresses memory Addresses) internal returns (string memory result) { @@ -96,6 +98,9 @@ abstract contract PeripheryAddressesLib is ScriptExtended { result = vm.serializeAddress("peripheryAddresses", "externalVaultRegistry", Addresses.externalVaultRegistry); result = vm.serializeAddress("peripheryAddresses", "kinkIRMFactory", Addresses.kinkIRMFactory); result = vm.serializeAddress("peripheryAddresses", "kinkyIRMFactory", Addresses.kinkyIRMFactory); + result = vm.serializeAddress( + "peripheryAddresses", "fixedCyclicalBinaryIRMFactory", Addresses.fixedCyclicalBinaryIRMFactory + ); result = vm.serializeAddress("peripheryAddresses", "adaptiveCurveIRMFactory", Addresses.adaptiveCurveIRMFactory); result = vm.serializeAddress("peripheryAddresses", "irmRegistry", Addresses.irmRegistry); result = vm.serializeAddress("peripheryAddresses", "swapper", Addresses.swapper); @@ -127,6 +132,8 @@ abstract contract PeripheryAddressesLib is ScriptExtended { Addresses.governorAccessControlEmergencyFactory ); result = vm.serializeAddress("peripheryAddresses", "capRiskStewardFactory", Addresses.capRiskStewardFactory); + result = + vm.serializeAddress("peripheryAddresses", "eulerEarnPublicAllocator", Addresses.eulerEarnPublicAllocator); } function deserializePeripheryAddresses(string memory json) internal pure returns (PeripheryAddresses memory) { @@ -136,6 +143,7 @@ abstract contract PeripheryAddressesLib is ScriptExtended { externalVaultRegistry: getAddressFromJson(json, ".externalVaultRegistry"), kinkIRMFactory: getAddressFromJson(json, ".kinkIRMFactory"), kinkyIRMFactory: getAddressFromJson(json, ".kinkyIRMFactory"), + fixedCyclicalBinaryIRMFactory: getAddressFromJson(json, ".fixedCyclicalBinaryIRMFactory"), adaptiveCurveIRMFactory: getAddressFromJson(json, ".adaptiveCurveIRMFactory"), irmRegistry: getAddressFromJson(json, ".irmRegistry"), swapper: getAddressFromJson(json, ".swapper"), @@ -152,7 +160,8 @@ abstract contract PeripheryAddressesLib is ScriptExtended { edgeFactoryPerspective: getAddressFromJson(json, ".edgeFactoryPerspective"), termsOfUseSigner: getAddressFromJson(json, ".termsOfUseSigner"), governorAccessControlEmergencyFactory: getAddressFromJson(json, ".governorAccessControlEmergencyFactory"), - capRiskStewardFactory: getAddressFromJson(json, ".capRiskStewardFactory") + capRiskStewardFactory: getAddressFromJson(json, ".capRiskStewardFactory"), + eulerEarnPublicAllocator: getAddressFromJson(json, ".eulerEarnPublicAllocator") }); } } @@ -581,11 +590,11 @@ abstract contract ScriptUtils is if (adapter == address(0) || counter > 1) { if (isExternalVault && bytes(provider).length == bytes("ExternalVault|").length + 42) { adapter = _toAddress(_substring(provider, bytes("ExternalVault|").length, type(uint256).max)); + counter = 0; } else if (bytes(provider).length == 42) { adapter = _toAddress(provider); + counter = 0; } - - counter = 0; } if ((adapter == address(0) && bytes(provider).length != bytes("ExternalVault|").length) || counter > 1) { @@ -688,12 +697,15 @@ abstract contract ScriptUtils is return result; } - function encodeAmountCaps(address[] storage assets, mapping(address => uint256 amountsNoDecimals) storage caps) - internal - { + function encodeAmountCaps( + address[] storage assets, + mapping(address => uint256 amountsNoDecimals) storage caps, + mapping(address => bool) storage encoded + ) internal { for (uint256 i = 0; i < assets.length; ++i) { address asset = assets[i]; - caps[asset] = encodeAmountCap(asset, caps[asset], true); + if (!encoded[asset]) caps[asset] = encodeAmountCap(asset, caps[asset], true); + encoded[asset] = true; } } @@ -848,6 +860,10 @@ abstract contract BatchBuilder is ScriptUtils { clearCriticalItems(); } + function getBatchItems() internal view returns (IEVC.BatchItem[] memory) { + return batchItems; + } + function clearBatchItems() internal { delete batchItems; } @@ -873,10 +889,14 @@ abstract contract BatchBuilder is ScriptUtils { function executeBatchPrank(address caller) internal { if (batchItems.length == 0) return; - console.log("Pranking the batch execution as %s on the EVC (%s)\n", caller, coreAddresses.evc); - for (uint256 i = 0; i < batchItems.length; ++i) { - batchItems[i].onBehalfOfAccount = caller; + if ( + batchItems[i].onBehalfOfAccount != address(0) + && !IEVC(coreAddresses.evc).haveCommonOwner(batchItems[i].onBehalfOfAccount, caller) + && !IEVC(coreAddresses.evc).isAccountOperatorAuthorized(batchItems[i].onBehalfOfAccount, caller) + ) { + batchItems[i].onBehalfOfAccount = caller; + } } vm.prank(caller); @@ -1030,6 +1050,33 @@ abstract contract BatchBuilder is ScriptUtils { vm.writeJson(vm.serializeString("timelockCalls", key, json), path); } + function toString(IEVC.BatchItem[] memory items) internal pure returns (string memory) { + string memory result = "["; + for (uint256 i = 0; i < items.length; ++i) { + result = string.concat(result, toString(items[i])); + if (i < items.length - 1) { + result = string.concat(result, ","); + } + } + return string.concat(result, "]"); + } + + function toString(IEVC.BatchItem memory item) internal pure returns (string memory) { + return string( + abi.encodePacked( + "[\"", + vm.toString(item.targetContract), + "\",\"", + vm.toString(item.onBehalfOfAccount), + "\",", + vm.toString(item.value), + ",\"", + vm.toString(item.data), + "\"]" + ) + ); + } + function grantRole(address accessController, bytes32 role, address account) internal { addBatchItem(accessController, abi.encodeCall(AccessControl.grantRole, (role, account))); } diff --git a/script/utils/check-contract-verification.js b/script/utils/check-contract-verification.js new file mode 100644 index 00000000..8a563a66 --- /dev/null +++ b/script/utils/check-contract-verification.js @@ -0,0 +1,420 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +// Try to load dotenv if available +let dotenv; +try { + dotenv = require('dotenv'); +} catch (e) { + // dotenv not available, will use process.env directly +} + +// Manual .env file loader as fallback +function loadEnvFile() { + try { + const envPath = path.join(process.cwd(), '.env'); + if (fs.existsSync(envPath)) { + const envContent = fs.readFileSync(envPath, 'utf8'); + const lines = envContent.split('\n'); + + lines.forEach(line => { + line = line.trim(); + if (line && !line.startsWith('#') && line.includes('=')) { + const [key, ...valueParts] = line.split('='); + let value = valueParts.join('=').trim(); + // Remove surrounding quotes if present + if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { + value = value.slice(1, -1); + } + if (key && value) { + process.env[key] = value; + } + } + }); + + logInfo('Loaded .env file manually'); + return true; + } + } catch (error) { + logWarning(`Failed to load .env file manually: ${error.message}`); + } + return false; +} + +// Configuration - will be set by command line arguments +let CONFIG = { + // Rate limiting: max requests per second + maxRequestsPerSecond: 1, // Conservative: 1 request per second + // Delay between requests in milliseconds + requestDelay: 1500, // 1.5 seconds between requests + // Retry configuration + maxRetries: 3, + baseRetryDelay: 3000, // 3 seconds base delay +}; + +// Function to load configuration from command line and environment +function loadConfig(args) { + // Load .env file if dotenv is available + if (dotenv) { + dotenv.config(); + logInfo('Loaded .env file using dotenv package'); + } else { + logWarning('dotenv package not available - trying manual .env loading'); + loadEnvFile(); + } + + // Parse command line arguments + let chainId, apiKey; + + for (let i = 0; i < args.length; i++) { + if (args[i] === '--chain-id' && i + 1 < args.length) { + chainId = args[i + 1]; + i++; // Skip next argument since we consumed it + } else if (args[i] === '--api-key' && i + 1 < args.length) { + apiKey = args[i + 1]; + i++; // Skip next argument since we consumed it + } + } + + if (chainId) { + // Try to get URL and API key from environment variables + const urlVar = `VERIFIER_URL_${chainId}`; + const apiKeyVar = `VERIFIER_API_KEY_${chainId}`; + + const baseUrl = process.env[urlVar]; + const envApiKey = process.env[apiKeyVar]; + + // Debug: show what we're looking for + logInfo(`Looking for environment variables: ${urlVar} and ${apiKeyVar}`); + logInfo(`Available environment variables: ${Object.keys(process.env).filter(key => key.startsWith('VERIFIER_')).join(', ')}`); + + if (!baseUrl) { + throw new Error(`No VERIFIER_URL_${chainId} found in environment variables. Available VERIFIER_* variables: ${Object.keys(process.env).filter(key => key.startsWith('VERIFIER_')).join(', ')}`); + } + + CONFIG.baseUrl = baseUrl; + CONFIG.apiKey = apiKey || envApiKey || ''; + + logInfo(`Using chain ID: ${chainId}`); + logInfo(`Base URL: ${baseUrl}`); + logInfo(`API Key: ${CONFIG.apiKey ? '✓ Set' : '✗ Not set'}`); + + } else { + // Fallback to default values or environment variables + CONFIG.baseUrl = process.env.VERIFIER_URL || 'https://api.etherscan.io/api'; + CONFIG.apiKey = apiKey || process.env.VERIFIER_API_KEY || ''; + + logInfo(`Using default configuration`); + logInfo(`Base URL: ${CONFIG.baseUrl}`); + logInfo(`API Key: ${CONFIG.apiKey ? '✓ Set' : '✗ Not set'}`); + } + + // Adjust rate limiting based on the explorer + if (CONFIG.baseUrl.includes('lineascan')) { + CONFIG.maxRequestsPerSecond = 1; + CONFIG.requestDelay = 1500; + logInfo(`Lineascan detected: Using conservative rate limiting (1 req/sec)`); + } else if (CONFIG.baseUrl.includes('etherscan')) { + CONFIG.maxRequestsPerSecond = 5; + CONFIG.requestDelay = 1000 / 5; + logInfo(`Etherscan detected: Using standard rate limiting (5 req/sec)`); + } else { + CONFIG.maxRequestsPerSecond = 2; + CONFIG.requestDelay = 1000 / 2; + logInfo(`Generic explorer: Using moderate rate limiting (2 req/sec)`); + } +} + +// Colors for console output +const colors = { + reset: '\x1b[0m', + bright: '\x1b[1m', + red: '\x1b[31m', + green: '\x1b[32m', + yellow: '\x1b[33m', + blue: '\x1b[34m', + magenta: '\x1b[35m', + cyan: '\x1b[36m', +}; + +function log(message, color = 'reset') { + console.log(`${colors[color]}${message}${colors.reset}`); +} + +function logError(message) { + console.error(`${colors.red}ERROR: ${message}${colors.reset}`); +} + +function logSuccess(message) { + console.log(`${colors.green}✓ ${message}${colors.reset}`); +} + +function logWarning(message) { + console.log(`${colors.yellow}⚠ ${message}${colors.reset}`); +} + +function logInfo(message) { + console.log(`${colors.blue}ℹ ${message}${colors.reset}`); +} + +// Sleep function for rate limiting +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +// Check if a contract is verified with retry logic +async function checkContractVerification(address, retryCount = 0) { + try { + // First try to get the ABI - this will only work for verified contracts + const abiUrl = `${CONFIG.baseUrl}?module=contract&action=getabi&address=${address}&apikey=${CONFIG.apiKey}`; + + const abiResponse = await fetch(abiUrl); + const abiData = await abiResponse.json(); + + // Check for rate limit errors (Lineascan specific message) + if (abiData.message && (abiData.message.includes('rate limit') || abiData.message.includes('Max calls per sec'))) { + if (retryCount < CONFIG.maxRetries) { + const delay = CONFIG.baseRetryDelay * Math.pow(2, retryCount); // Exponential backoff + logWarning(`Rate limit hit for ${address}, retrying in ${delay/1000}s... (attempt ${retryCount + 1}/${CONFIG.maxRetries})`); + await sleep(delay); + return checkContractVerification(address, retryCount + 1); + } else { + return { + address, + verified: false, + reason: `Rate limit exceeded after ${CONFIG.maxRetries} retries` + }; + } + } + + if (abiData.status === '1' && abiData.result !== 'Contract source code not verified') { + // Contract is verified - get additional details + const sourceUrl = `${CONFIG.baseUrl}?module=contract&action=getsourcecode&address=${address}&apikey=${CONFIG.apiKey}`; + const sourceResponse = await fetch(sourceUrl); + const sourceData = await sourceResponse.json(); + + // Check for rate limit errors in source code request (Lineascan specific message) + if (sourceData.message && (sourceData.message.includes('rate limit') || sourceData.message.includes('Max calls per sec'))) { + if (retryCount < CONFIG.maxRetries) { + const delay = CONFIG.baseRetryDelay * Math.pow(2, retryCount); // Exponential backoff + logWarning(`Rate limit hit for source code of ${address}, retrying in ${delay/1000}s... (attempt ${retryCount + 1}/${CONFIG.maxRetries})`); + await sleep(delay); + return checkContractVerification(address, retryCount + 1); + } else { + return { + address, + verified: true, + name: 'Verified (details unavailable due to rate limit)', + compiler: 'Unknown', + optimization: 'Unknown', + runs: 'Unknown' + }; + } + } + + if (sourceData.status === '1') { + const result = sourceData.result[0]; + return { + address, + verified: true, + name: result.ContractName || 'Unknown', + compiler: result.CompilerVersion || 'Unknown', + optimization: result.OptimizationUsed === '1' ? 'Yes' : 'No', + runs: result.Runs || 'N/A' + }; + } else { + return { + address, + verified: true, + name: 'Verified (details unavailable)', + compiler: 'Unknown', + optimization: 'Unknown', + runs: 'Unknown' + }; + } + } else { + // Contract is not verified + return { + address, + verified: false, + reason: abiData.result || 'Contract not verified' + }; + } + } catch (error) { + if (retryCount < CONFIG.maxRetries) { + const delay = CONFIG.baseRetryDelay * Math.pow(2, retryCount); // Exponential backoff + logWarning(`Request failed for ${address}, retrying in ${delay/1000}s... (attempt ${retryCount + 1}/${CONFIG.maxRetries})`); + await sleep(delay); + return checkContractVerification(address, retryCount + 1); + } else { + return { + address, + verified: false, + reason: `Request failed after ${CONFIG.maxRetries} retries: ${error.message}` + }; + } + } +} + +// Main function to process all addresses +async function checkAllContracts(jsonFilePath) { + try { + // Check if file exists + if (!fs.existsSync(jsonFilePath)) { + logError(`File not found: ${jsonFilePath}`); + process.exit(1); + } + + // Read and parse JSON file + const fileContent = fs.readFileSync(jsonFilePath, 'utf8'); + const contracts = JSON.parse(fileContent); + + log(`\n${colors.bright}Contract Verification Status Checker${colors.reset}`); + log(`===============================================`); + log(`Input file: ${jsonFilePath}`); + log(`Total contracts to check: ${Object.keys(contracts).length}`); + log(`Rate limit: ${CONFIG.maxRequestsPerSecond} requests/second`); + log(`Retry attempts: ${CONFIG.maxRetries}`); + log(``); + + if (!CONFIG.apiKey) { + logWarning('No API key provided. Some explorers may have rate limits.'); + logInfo('Set VERIFIER_API_KEY_ environment variable for better access.'); + } + + const results = []; + const addresses = Object.values(contracts); + const names = Object.keys(contracts); + + // Process addresses with rate limiting + for (let i = 0; i < addresses.length; i++) { + const address = addresses[i]; + const name = names[i]; + + logInfo(`Checking ${name} (${address})... [${i + 1}/${addresses.length}]`); + + const result = await checkContractVerification(address); + result.contractName = name; + results.push(result); + + // Rate limiting delay + if (i < addresses.length - 1) { + logInfo(`Waiting ${CONFIG.requestDelay/1000}s before next request...`); + await sleep(CONFIG.requestDelay); + } + } + + // Display results + log(`\n${colors.bright}Results:${colors.reset}`); + log(`========`); + + let verifiedCount = 0; + let unverifiedCount = 0; + + results.forEach(result => { + if (result.verified) { + verifiedCount++; + logSuccess(`${result.contractName}: ${result.address}`); + log(` Name: ${result.name}`); + log(` Compiler: ${result.compiler}`); + log(` Optimization: ${result.optimization}`); + log(` Runs: ${result.runs}`); + } else { + unverifiedCount++; + logError(`${result.contractName}: ${result.address}`); + log(` Reason: ${result.reason}`); + } + log(``); + }); + + // Summary + log(`\n${colors.bright}Summary:${colors.reset}`); + log(`========`); + log(`Total contracts: ${results.length}`); + log(`Verified: ${colors.green}${verifiedCount}${colors.reset}`); + log(`Unverified: ${colors.red}${unverifiedCount}${colors.reset}`); + + // Results are only displayed in console, no files saved + + } catch (error) { + logError(`Failed to process contracts: ${error.message}`); + process.exit(1); + } +} + +// CLI argument handling +function showUsage() { + log(`\n${colors.bright}Usage:${colors.reset}`); + log(`node checkContractVerification.js [options] `); + log(`\n${colors.bright}Options:${colors.reset}`); + log(`--chain-id Chain ID to use (e.g., 1 for Ethereum, 130 for Unichain)`); + log(`--api-key Override API key from environment variables`); + log(`--help, -h Show this help message`); + log(`\n${colors.bright}Environment Variables:${colors.reset}`); + log(`VERIFIER_URL_ Explorer URL for specific chain ID (e.g., VERIFIER_URL_1, VERIFIER_URL_130)`); + log(`VERIFIER_API_KEY_ API key for specific chain ID (e.g., VERIFIER_API_KEY_1, VERIFIER_API_KEY_130)`); + log(`VERIFIER_URL Default explorer URL (fallback)`); + log(`VERIFIER_API_KEY Default API key (fallback)`); + log(`\n${colors.bright}Examples:${colors.reset}`); + log(`# Check contracts on Ethereum mainnet (chain ID 1)`); + log(`node checkContractVerification.js --chain-id 1 contracts.json`); + log(`\n# Check contracts on Unichain (chain ID 130)`); + log(`node checkContractVerification.js --chain-id 130 contracts.json`); + log(`\n# Override API key for a specific chain`); + log(`node checkContractVerification.js --chain-id 1 --api-key your_key contracts.json`); + log(`\n# Use default configuration`); + log(`node checkContractVerification.js contracts.json`); + log(`\n${colors.bright}Example JSON format:${colors.reset}`); + log(`{ + "balanceTracker": "0x0D52d06ceB8Dcdeeb40Cfd9f17489B350dD7F8a3", + "eVaultFactory": "0x29a56a1b8214D9Cf7c5561811750D5cBDb45CC8e" +}`); +} + +// Main execution +async function main() { + const args = process.argv.slice(2); + + if (args.length === 0 || args.includes('--help') || args.includes('-h')) { + showUsage(); + process.exit(0); + } + + // Load configuration from command line and environment + try { + loadConfig(args); + } catch (error) { + logError(`Configuration error: ${error.message}`); + showUsage(); + process.exit(1); + } + + // Find the JSON file path (first non-flag argument) + const jsonFilePath = args.find(arg => !arg.startsWith('--')); + + if (!jsonFilePath || !jsonFilePath.endsWith('.json')) { + logError('Please provide a JSON file path'); + showUsage(); + process.exit(1); + } + + await checkAllContracts(jsonFilePath); +} + +// Handle unhandled promise rejections +process.on('unhandledRejection', (reason, promise) => { + logError(`Unhandled Rejection at: ${promise}, reason: ${reason}`); + process.exit(1); +}); + +// Run the script +if (require.main === module) { + main().catch(error => { + logError(`Script failed: ${error.message}`); + process.exit(1); + }); +} + +module.exports = { checkContractVerification, checkAllContracts }; \ No newline at end of file diff --git a/script/utils/executeForgeScript.sh b/script/utils/executeForgeScript.sh index cc61ee20..727624dc 100755 --- a/script/utils/executeForgeScript.sh +++ b/script/utils/executeForgeScript.sh @@ -124,7 +124,52 @@ if [[ "$@" == *"--no-stub-oracle"* ]]; then no_stub_oracle="--no-stub-oracle" fi -if [[ -n "$safe_address" ]] || [[ -n "$simulate_safe_address" ]]; then +if [[ "$@" == *"--skip-oft-hub-chain-config"* ]]; then + set -- "${@/--skip-oft-hub-chain-config/}" + skip_oft_hub_chain_config="--skip-oft-hub-chain-config" +fi + +if [[ "$@" == *"--check-phased-out-vaults"* ]]; then + set -- "${@/--check-phased-out-vaults/}" + check_phased_out_vaults="--check-phased-out-vaults" +fi + +if [[ "$@" == *"--from-block"* ]]; then + from_block=$(echo "$@" | grep -o '\--from-block [^ ]*' | cut -d ' ' -f 2) + set -- $(echo "$@" | sed "s/--from-block $from_block//") +fi + +if [[ "$@" == *"--to-block"* ]]; then + to_block=$(echo "$@" | grep -o '\--to-block [^ ]*' | cut -d ' ' -f 2) + set -- $(echo "$@" | sed "s/--to-block $to_block//") +fi + +if [[ "$@" == *"--source-wallet"* ]]; then + source_wallet=$(echo "$@" | grep -o '\--source-wallet [^ ]*' | cut -d ' ' -f 2) + set -- $(echo "$@" | sed "s/--source-wallet $source_wallet//") +fi + +if [[ "$@" == *"--destination-wallet"* ]]; then + destination_wallet=$(echo "$@" | grep -o '\--destination-wallet [^ ]*' | cut -d ' ' -f 2) + set -- $(echo "$@" | sed "s/--destination-wallet $destination_wallet//") +fi + +if [[ "$@" == *"--source-account-id"* ]]; then + source_account_id=$(echo "$@" | grep -o '\--source-account-id [^ ]*' | cut -d ' ' -f 2) + set -- $(echo "$@" | sed "s/--source-account-id $source_account_id//") +fi + +if [[ "$@" == *"--destination-account-id"* ]]; then + destination_account_id=$(echo "$@" | grep -o '\--destination-account-id [^ ]*' | cut -d ' ' -f 2) + set -- $(echo "$@" | sed "s/--destination-account-id $destination_account_id//") +fi + +if [[ "$@" == *"--path "* ]]; then + path=$(echo "$@" | grep -o -- '--path [^ ]*' | cut -d ' ' -f 2) + set -- $(echo "$@" | sed "s#--path $path##") +fi + +if [[ -n "$safe_address" ]] || [[ -n "$simulate_safe_address" ]] || [[ -n "$path" ]]; then if [[ "$@" != *"--ffi"* ]]; then set -- "$@" --ffi fi @@ -134,10 +179,13 @@ if ! env broadcast=$broadcast safe_address=$safe_address safe_nonce=$safe_nonce safe_owner_simulate=$safe_owner_simulate skip_pending_simulation=$skip_pending_simulation \ simulate_safe_address=$simulate_safe_address simulate_timelock_address=$simulate_timelock_address \ timelock_address=$timelock_address timelock_id=$timelock_id timelock_salt=$timelock_salt \ - risk_steward_address=$risk_steward_address \ + risk_steward_address=$risk_steward_address path=$path \ emergency_ltv_collateral=$emergency_ltv_collateral emergency_ltv_borrowing=$emergency_ltv_borrowing \ emergency_caps=$emergency_caps emergency_operations=$emergency_operations \ - vault_address=$vault_address no_stub_oracle=$no_stub_oracle \ + vault_address=$vault_address no_stub_oracle=$no_stub_oracle skip_oft_hub_chain_config=$skip_oft_hub_chain_config \ + check_phased_out_vaults=$check_phased_out_vaults \ + from_block=$from_block to_block=$to_block source_wallet=$source_wallet destination_wallet=$destination_wallet \ + source_account_id=$source_account_id destination_account_id=$destination_account_id \ forge script script/$scriptPath --rpc-url "$DEPLOYMENT_RPC_URL" $broadcast --legacy --slow --with-gas-price $gasPrice $@; then exit 1 fi diff --git a/script/utils/verifyContracts.sh b/script/utils/verifyContracts.sh index 46729965..8c0f3f37 100755 --- a/script/utils/verifyContracts.sh +++ b/script/utils/verifyContracts.sh @@ -62,6 +62,7 @@ function verify_contract { curl -d "address=$contractAddress" "$verifier_url?module=contract&action=verifyproxycontract&apikey=$verifier_api_key" fi + sleep 5 return $result } @@ -198,18 +199,23 @@ function verify_broadcast { elif [[ $transactionType == "CREATE" && $verificationSuccessful != true ]]; then local initCode=$(echo $tx | jq -r '.transaction.input') - if [ -d "out-euler-earn" ] && [ $eulerEarnIndex -le 1 ]; then + if [ -d "out-euler-earn" ] && [ $eulerEarnIndex -le 2 ]; then # try to verify as EulerEarn contracts local src="lib/euler-earn/src" - local verificationOptions="--via-ir --num-of-optimizations 800 --compiler-version 0.8.26 --root lib/euler-earn" - local compilerOptions="--via-ir --optimize --optimizer-runs 800 --use 0.8.26" + local verificationOptions="--via-ir --num-of-optimizations 200 --compiler-version 0.8.26 --root lib/euler-earn" + local compilerOptions="--via-ir --optimize --optimizer-runs 200 --use 0.8.26" while true; do case $eulerEarnIndex in 0) # try to verify as EulerEarnFactory contractName=EulerEarnFactory - constructorBytesSize=96 + constructorBytesSize=128 + ;; + 1) + # try to verify as PublicAllocator + contractName=PublicAllocator + constructorBytesSize=32 ;; *) break diff --git a/src/HookTarget/HookTargetAccessControlKeyring.sol b/src/HookTarget/HookTargetAccessControlKeyring.sol index 6c341063..674caed2 100644 --- a/src/HookTarget/HookTargetAccessControlKeyring.sol +++ b/src/HookTarget/HookTargetAccessControlKeyring.sol @@ -100,11 +100,21 @@ contract HookTargetAccessControlKeyring is BaseHookTarget, SelectorAccessControl /// @dev If the EVC owner is not registered yet, the account is assumed to be the owner /// @param account The address to check credential for /// @return bool True if the EVC owner of the account has valid Keyring credential - function checkKeyringCredential(address account) external view returns (bool) { + function checkKeyringCredential(address account) public view returns (bool) { address owner = evc.getAccountOwner(account); return keyring.checkCredential(owner == address(0) ? account : owner, policyId); } + /// @notice Checks if the EVC owner of the account has a valid Keyring credential or the account has the wildcard + /// role + /// @dev For the Keyring credential, if the EVC owner is not registered yet, the account is assumed to be the owner + /// @param account The address to check credential or wildcard role for + /// @return bool True if the EVC owner of the account has a valid Keyring credential or the account has the wildcard + /// role + function checkKeyringCredentialOrWildCard(address account) external view returns (bool) { + return hasRole(WILD_CARD, account) || checkKeyringCredential(account); + } + /// @notice Authenticates both the caller and the specified account for access control /// @dev This function checks if either the caller or the account owner are authorized to call the function /// @param account The account to be authenticated diff --git a/src/IRM/IRMFixedCyclicalBinary.sol b/src/IRM/IRMFixedCyclicalBinary.sol new file mode 100644 index 00000000..d6aae2cb --- /dev/null +++ b/src/IRM/IRMFixedCyclicalBinary.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {IIRM} from "evk/InterestRateModels/IIRM.sol"; + +/// @title IRMFixedCyclicalBinary +/// @custom:security-contact security@euler.xyz +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice Implementation of an interest rate model, where interest rate cycles between two fixed values, +contract IRMFixedCyclicalBinary is IIRM { + /// @notice Interest rate applied during the first part of the cycle + uint256 public immutable primaryRate; + /// @notice Interest rate applied during the second part of the cycle + uint256 public immutable secondaryRate; + /// @notice Duration of the primary part of the cycle in seconds + uint256 public immutable primaryDuration; + /// @notice Duration of the secondary part of the cycle in seconds + uint256 public immutable secondaryDuration; + /// @notice Timestamp of the start of the first cycle + uint256 public immutable startTimestamp; + + /// @notice Error thrown when start timestamp is in the future + error BadStartTimestamp(); + /// @notice Error thrown when duration of either primary or secondary part of the cycle is zero + /// or when the whole cycle duration overflows uint + error BadDuration(); + + /// @notice Creates a fixed cyclical binary interest rate model + /// @param primaryRate_ Interest rate applied during the first part of the cycle + /// @param secondaryRate_ Interest rate applied during the second part of the cycle + /// @param primaryDuration_ Duration of the primary part of the cycle in seconds + /// @param secondaryDuration_ Duration of the secondary part of the cycle in seconds + /// @param startTimestamp_ Timestamp of the start of the first cycle + constructor( + uint256 primaryRate_, + uint256 secondaryRate_, + uint256 primaryDuration_, + uint256 secondaryDuration_, + uint256 startTimestamp_ + ) { + if (startTimestamp_ > block.timestamp) revert BadStartTimestamp(); + if ( + primaryDuration_ == 0 || secondaryDuration_ == 0 + || (type(uint256).max - primaryDuration_ < secondaryDuration_) + ) revert BadDuration(); + + primaryRate = primaryRate_; + secondaryRate = secondaryRate_; + primaryDuration = primaryDuration_; + secondaryDuration = secondaryDuration_; + startTimestamp = startTimestamp_; + } + + /// @inheritdoc IIRM + function computeInterestRate(address vault, uint256, uint256) external view override returns (uint256) { + if (msg.sender != vault) revert E_IRMUpdateUnauthorized(); + + return computeInterestRateInternal(); + } + + /// @inheritdoc IIRM + function computeInterestRateView(address, uint256, uint256) external view override returns (uint256) { + return computeInterestRateInternal(); + } + + function computeInterestRateInternal() internal view returns (uint256) { + uint256 timeSinceStart = block.timestamp - startTimestamp; + + return timeSinceStart % (primaryDuration + secondaryDuration) <= primaryDuration ? primaryRate : secondaryRate; + } +} diff --git a/src/IRMFactory/EulerFixedCyclicalBinaryIRMFactory.sol b/src/IRMFactory/EulerFixedCyclicalBinaryIRMFactory.sol new file mode 100644 index 00000000..3093e521 --- /dev/null +++ b/src/IRMFactory/EulerFixedCyclicalBinaryIRMFactory.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity ^0.8.0; + +import {BaseFactory} from "../BaseFactory/BaseFactory.sol"; +import {IRMFixedCyclicalBinary} from "../IRM/IRMFixedCyclicalBinary.sol"; +import {IEulerFixedCyclicalBinaryIRMFactory} from "./interfaces/IEulerFixedCyclicalBinaryIRMFactory.sol"; + +/// @title EulerFixedCyclicalBinaryIRMFactory +/// @custom:security-contact security@euler.xyz +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice A minimal factory for Fixed Cyclical Binary IRMs. +contract EulerFixedCyclicalBinaryIRMFactory is BaseFactory, IEulerFixedCyclicalBinaryIRMFactory { + // corresponds to 1000% APY + uint256 internal constant MAX_ALLOWED_INTEREST_RATE = 75986279153383989049; + + /// @notice Error thrown when the computed interest rate exceeds the maximum allowed limit. + error IRMFactory_ExcessiveInterestRate(); + + /// @notice Deploys a new IRMFixedCyclicalBinary. + /// @param primaryRate Interest rate applied during the first part of the cycle + /// @param secondaryRate Interest rate applied during the second part of the cycle + /// @param primaryDuration Duration of the primary part of the cycle in seconds + /// @param secondaryDuration Duration of the secondary part of the cycle in seconds + /// @param startTimestamp Timestamp of the start of the first cycle + /// @return The deployment address. + function deploy( + uint256 primaryRate, + uint256 secondaryRate, + uint256 primaryDuration, + uint256 secondaryDuration, + uint256 startTimestamp + ) external override returns (address) { + if (primaryRate > MAX_ALLOWED_INTEREST_RATE || secondaryRate > MAX_ALLOWED_INTEREST_RATE) { + revert IRMFactory_ExcessiveInterestRate(); + } + + IRMFixedCyclicalBinary irm = + new IRMFixedCyclicalBinary(primaryRate, secondaryRate, primaryDuration, secondaryDuration, startTimestamp); + + deploymentInfo[address(irm)] = DeploymentInfo(msg.sender, uint96(block.timestamp)); + deployments.push(address(irm)); + emit ContractDeployed(address(irm), msg.sender, block.timestamp); + return address(irm); + } +} diff --git a/src/IRMFactory/interfaces/IEulerFixedCyclicalBinaryIRMFactory.sol b/src/IRMFactory/interfaces/IEulerFixedCyclicalBinaryIRMFactory.sol new file mode 100644 index 00000000..6aa9fc42 --- /dev/null +++ b/src/IRMFactory/interfaces/IEulerFixedCyclicalBinaryIRMFactory.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +pragma solidity >=0.8.0; + +import {IFactory} from "../../BaseFactory/interfaces/IFactory.sol"; + +/// @title IEulerFixedCyclicalBinaryRMFactory +/// @custom:security-contact security@euler.xyz +/// @author Euler Labs (https://www.eulerlabs.com/) +/// @notice A minimal factory for EulerFixedCyclicalBinaryIRM. +interface IEulerFixedCyclicalBinaryIRMFactory is IFactory { + /// @notice Deploys a new IRMFixedCyclicalBinary. + /// @param primaryRate Interest rate applied during the first part of the cycle + /// @param secondaryRate Interest rate applied during the second part of the cycle + /// @param primaryDuration Duration of the primary part of the cycle in seconds + /// @param secondaryDuration Duration of the secondary part of the cycle in seconds + /// @param startTimestamp Timestamp of the start of the first cycle + /// @return The deployment address. + function deploy( + uint256 primaryRate, + uint256 secondaryRate, + uint256 primaryDuration, + uint256 secondaryDuration, + uint256 startTimestamp + ) external returns (address); +} diff --git a/src/Lens/EulerEarnVaultLens.sol b/src/Lens/EulerEarnVaultLens.sol index 7e5b6a1d..b8f3f992 100644 --- a/src/Lens/EulerEarnVaultLens.sol +++ b/src/Lens/EulerEarnVaultLens.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import { - IEulerEarn, IERC4626, MarketConfig, PendingUint192, PendingAddress + IEulerEarn, IERC4626, MarketConfig, PendingUint136, PendingAddress } from "euler-earn/interfaces/IEulerEarn.sol"; import {EVCUtil} from "ethereum-vault-connector/utils/EVCUtil.sol"; import {UtilsLens} from "./UtilsLens.sol"; @@ -34,6 +34,12 @@ contract EulerEarnVaultLens is Utils { result.totalShares = IEulerEarn(vault).totalSupply(); result.totalAssets = IEulerEarn(vault).totalAssets(); result.lostAssets = IEulerEarn(vault).lostAssets(); + + if (result.lostAssets > 0) { + uint256 coveredLostAssets = IEulerEarn(vault).convertToAssets(IEulerEarn(vault).balanceOf(address(1))); + result.lostAssets = result.lostAssets > coveredLostAssets ? result.lostAssets - coveredLostAssets : 0; + } + result.timelock = IEulerEarn(vault).timelock(); result.performanceFee = IEulerEarn(vault).fee(); result.feeReceiver = IEulerEarn(vault).feeRecipient(); @@ -44,7 +50,7 @@ contract EulerEarnVaultLens is Utils { result.evc = EVCUtil(vault).EVC(); result.permit2 = IEulerEarn(vault).permit2Address(); - PendingUint192 memory pendingTimelock = IEulerEarn(vault).pendingTimelock(); + PendingUint136 memory pendingTimelock = IEulerEarn(vault).pendingTimelock(); PendingAddress memory pendingGuardian = IEulerEarn(vault).pendingGuardian(); result.pendingTimelock = pendingTimelock.value; @@ -60,19 +66,46 @@ contract EulerEarnVaultLens is Utils { result.strategies = new EulerEarnVaultStrategyInfo[](IEulerEarn(vault).withdrawQueueLength()); for (uint256 i; i < result.strategies.length; ++i) { - IERC4626 strategy = IEulerEarn(vault).withdrawQueue(i); - MarketConfig memory config = IEulerEarn(vault).config(strategy); - PendingUint192 memory pendingConfig = IEulerEarn(vault).pendingCap(strategy); - - result.strategies[i].strategy = address(strategy); - result.strategies[i].assetsAllocated = strategy.previewRedeem(strategy.balanceOf(vault)); - result.strategies[i].currentAllocationCap = config.cap; - result.strategies[i].pendingAllocationCap = pendingConfig.value; - result.strategies[i].pendingAllocationCapValidAt = pendingConfig.validAt; - result.strategies[i].removableAt = config.removableAt; - result.strategies[i].info = utilsLens.getVaultInfoERC4626(result.strategies[i].strategy); + result.strategies[i] = getStrategyInfo(vault, address(IEulerEarn(vault).withdrawQueue(i))); + result.availableAssets += result.strategies[i].availableAssets; + } + + return result; + } + + function getStrategiesInfo(address vault, address[] calldata strategies) + public + view + returns (EulerEarnVaultStrategyInfo[] memory) + { + EulerEarnVaultStrategyInfo[] memory result = new EulerEarnVaultStrategyInfo[](strategies.length); + + for (uint256 i; i < strategies.length; ++i) { + result[i] = getStrategyInfo(vault, strategies[i]); } return result; } + + function getStrategyInfo(address _vault, address _strategy) + public + view + returns (EulerEarnVaultStrategyInfo memory) + { + IEulerEarn vault = IEulerEarn(_vault); + IERC4626 strategy = IERC4626(_strategy); + MarketConfig memory config = vault.config(strategy); + PendingUint136 memory pendingConfig = vault.pendingCap(strategy); + + return EulerEarnVaultStrategyInfo({ + strategy: _strategy, + allocatedAssets: vault.expectedSupplyAssets(strategy), + availableAssets: vault.maxWithdrawFromStrategy(strategy), + currentAllocationCap: config.cap, + pendingAllocationCap: pendingConfig.value, + pendingAllocationCapValidAt: pendingConfig.validAt, + removableAt: config.removableAt, + info: utilsLens.getVaultInfoERC4626(_strategy) + }); + } } diff --git a/src/Lens/IRMLens.sol b/src/Lens/IRMLens.sol index 7d06a177..20f3c537 100644 --- a/src/Lens/IRMLens.sol +++ b/src/Lens/IRMLens.sol @@ -6,15 +6,26 @@ import {Utils} from "./Utils.sol"; import {IFactory} from "../BaseFactory/interfaces/IFactory.sol"; import {IRMLinearKink} from "evk/InterestRateModels/IRMLinearKink.sol"; import {IRMAdaptiveCurve} from "../IRM/IRMAdaptiveCurve.sol"; +import {IRMLinearKinky} from "../IRM/IRMLinearKinky.sol"; +import {IRMFixedCyclicalBinary} from "../IRM/IRMFixedCyclicalBinary.sol"; import "./LensTypes.sol"; contract IRMLens is Utils { address public immutable kinkIRMFactory; address public immutable adaptiveCurveIRMFactory; + address public immutable kinkyIRMFactory; + address public immutable fixedCyclicalBinaryIRMFactory; - constructor(address _kinkIRMFactory, address _adaptiveCurveIRMFactory) { + constructor( + address _kinkIRMFactory, + address _adaptiveCurveIRMFactory, + address _kinkyIRMFactory, + address _fixedCyclicalBinaryIRMFactory + ) { kinkIRMFactory = _kinkIRMFactory; adaptiveCurveIRMFactory = _adaptiveCurveIRMFactory; + kinkyIRMFactory = _kinkyIRMFactory; + fixedCyclicalBinaryIRMFactory = _fixedCyclicalBinaryIRMFactory; } function getInterestRateModelInfo(address irm) public view returns (InterestRateModelDetailedInfo memory) { @@ -48,7 +59,30 @@ contract IRMLens is Utils { adjustmentSpeed: IRMAdaptiveCurve(irm).ADJUSTMENT_SPEED() }) ); + } else if (IFactory(kinkyIRMFactory).isValidDeployment(irm)) { + result.interestRateModelType = InterestRateModelType.KINKY; + result.interestRateModelParams = abi.encode( + KinkyIRMInfo({ + baseRate: IRMLinearKinky(irm).baseRate(), + slope: IRMLinearKinky(irm).slope(), + shape: IRMLinearKinky(irm).shape(), + kink: IRMLinearKinky(irm).kink(), + cutoff: IRMLinearKinky(irm).cutoff() + }) + ); + } else if (IFactory(fixedCyclicalBinaryIRMFactory).isValidDeployment(irm)) { + result.interestRateModelType = InterestRateModelType.FIXED_CYCLICAL_BINARY; + result.interestRateModelParams = abi.encode( + FixedCyclicalBinaryIRMInfo({ + primaryRate: IRMFixedCyclicalBinary(irm).primaryRate(), + secondaryRate: IRMFixedCyclicalBinary(irm).secondaryRate(), + primaryDuration: IRMFixedCyclicalBinary(irm).primaryDuration(), + secondaryDuration: IRMFixedCyclicalBinary(irm).secondaryDuration(), + startTimestamp: IRMFixedCyclicalBinary(irm).startTimestamp() + }) + ); } + return result; } } diff --git a/src/Lens/LensTypes.sol b/src/Lens/LensTypes.sol index 1df12dd3..8dcbb60f 100644 --- a/src/Lens/LensTypes.sol +++ b/src/Lens/LensTypes.sol @@ -170,7 +170,9 @@ struct InterestRateInfo { enum InterestRateModelType { UNKNOWN, KINK, - ADAPTIVE_CURVE + ADAPTIVE_CURVE, + KINKY, + FIXED_CYCLICAL_BINARY } struct InterestRateModelDetailedInfo { @@ -195,6 +197,22 @@ struct AdaptiveCurveIRMInfo { int256 adjustmentSpeed; } +struct KinkyIRMInfo { + uint256 baseRate; + uint256 slope; + uint256 shape; + uint256 kink; + uint256 cutoff; +} + +struct FixedCyclicalBinaryIRMInfo { + uint256 primaryRate; + uint256 secondaryRate; + uint256 primaryDuration; + uint256 secondaryDuration; + uint256 startTimestamp; +} + struct AccountRewardInfo { uint256 timestamp; address account; @@ -380,6 +398,7 @@ struct EulerEarnVaultInfoFull { uint256 totalShares; uint256 totalAssets; uint256 lostAssets; + uint256 availableAssets; uint256 timelock; uint256 performanceFee; address feeReceiver; @@ -399,7 +418,8 @@ struct EulerEarnVaultInfoFull { struct EulerEarnVaultStrategyInfo { address strategy; - uint256 assetsAllocated; + uint256 allocatedAssets; + uint256 availableAssets; uint256 currentAllocationCap; uint256 pendingAllocationCap; uint256 pendingAllocationCapValidAt; diff --git a/test/IRM/IRMFixedCyclicalBinary.t.sol b/test/IRM/IRMFixedCyclicalBinary.t.sol new file mode 100644 index 00000000..d1e9959d --- /dev/null +++ b/test/IRM/IRMFixedCyclicalBinary.t.sol @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.13; + +import {Test} from "forge-std/Test.sol"; +import {IIRM} from "evk/InterestRateModels/IIRM.sol"; +import {IRMFixedCyclicalBinary} from "../../src/IRM/IRMFixedCyclicalBinary.sol"; +import {EulerFixedCyclicalBinaryIRMFactory} from "../../src/IRMFactory/EulerFixedCyclicalBinaryIRMFactory.sol"; +import {MathTesting} from "../utils/MathTesting.sol"; + +import {console} from "forge-std/console.sol"; + +contract IRMFixedCyclicalBinaryTest is Test, MathTesting { + IRMFixedCyclicalBinary irm; + EulerFixedCyclicalBinaryIRMFactory factory; + + uint256 constant PRIMARY_RATE = 1; + uint256 constant SECONDARY_RATE = 2; + uint256 constant PRIMARY_DURATION = 28 days; + uint256 constant SECONDARY_DURATION = 2 days; + + // corresponds to 1000% APY + uint256 internal constant MAX_ALLOWED_INTEREST_RATE = 75986279153383989049; + + function setUp() public { + irm = new IRMFixedCyclicalBinary( + PRIMARY_RATE, SECONDARY_RATE, PRIMARY_DURATION, SECONDARY_DURATION, block.timestamp + ); + + factory = new EulerFixedCyclicalBinaryIRMFactory(); + } + + function test_OnlyVaultCanMutateIRMState() public { + vm.expectRevert(IIRM.E_IRMUpdateUnauthorized.selector); + irm.computeInterestRate(address(1234), 5, 6); + + vm.prank(address(1234)); + irm.computeInterestRate(address(1234), 5, 6); + } + + function test_ExpectRevertStartTimeInFuture() public { + vm.expectRevert(IRMFixedCyclicalBinary.BadStartTimestamp.selector); + new IRMFixedCyclicalBinary( + PRIMARY_RATE, SECONDARY_RATE, PRIMARY_DURATION, SECONDARY_DURATION, block.timestamp + 1 + ); + } + + function test_ExpectRevertPrimaryDurationZero() public { + vm.expectRevert(IRMFixedCyclicalBinary.BadDuration.selector); + new IRMFixedCyclicalBinary(PRIMARY_RATE, SECONDARY_RATE, 0, SECONDARY_DURATION, block.timestamp); + } + + function test_ExpectRevertSecondaryDurationZero() public { + vm.expectRevert(IRMFixedCyclicalBinary.BadDuration.selector); + new IRMFixedCyclicalBinary(PRIMARY_RATE, SECONDARY_RATE, PRIMARY_DURATION, 0, block.timestamp); + } + + function test_ExpectRevertCycleDurationOverflows() public { + vm.expectRevert(IRMFixedCyclicalBinary.BadDuration.selector); + new IRMFixedCyclicalBinary(PRIMARY_RATE, SECONDARY_RATE, type(uint256).max - 1, 2, block.timestamp); + } + + function test_RateAtDeployment() public view { + assertEq(getIr(), PRIMARY_RATE); + } + + function test_RateAtEndOfPrimaryPeriod() public { + vm.warp(block.timestamp + PRIMARY_DURATION - 1); + assertEq(getIr(), PRIMARY_RATE); + + vm.warp(block.timestamp + 1); + assertEq(getIr(), PRIMARY_RATE); + + vm.warp(block.timestamp + 1); + assertEq(getIr(), SECONDARY_RATE); + } + + function test_RateAtEndOfCycle() public { + vm.warp(block.timestamp + PRIMARY_DURATION + SECONDARY_DURATION - 1); + assertEq(getIr(), SECONDARY_RATE); + + vm.warp(block.timestamp + 1); + assertEq(getIr(), PRIMARY_RATE); + } + + function test_CycleRates(uint256 timeElapsed, uint256 primaryDuration, uint256 secondaryDuration) public { + timeElapsed = bound(timeElapsed, 0, 1000 days); + primaryDuration = bound(primaryDuration, 1, 100 days); + secondaryDuration = bound(secondaryDuration, 1, 100 days); + + irm = + IRMFixedCyclicalBinary(factory.deploy(PRIMARY_RATE, SECONDARY_RATE, primaryDuration, secondaryDuration, 0)); + + vm.warp(timeElapsed); + + uint256 cyclesElapsed = timeElapsed / (primaryDuration + secondaryDuration); + + if (timeElapsed - cyclesElapsed * (primaryDuration + secondaryDuration) <= primaryDuration) { + assertEq(getIr(), PRIMARY_RATE); + } else { + assertEq(getIr(), SECONDARY_RATE); + } + } + + function test_ExpectRevertFactoryRateTooHigh() public { + vm.expectRevert(EulerFixedCyclicalBinaryIRMFactory.IRMFactory_ExcessiveInterestRate.selector); + factory.deploy(MAX_ALLOWED_INTEREST_RATE + 1, SECONDARY_RATE, PRIMARY_DURATION, SECONDARY_DURATION, 0); + vm.expectRevert(EulerFixedCyclicalBinaryIRMFactory.IRMFactory_ExcessiveInterestRate.selector); + factory.deploy(PRIMARY_RATE, MAX_ALLOWED_INTEREST_RATE + 1, PRIMARY_DURATION, SECONDARY_DURATION, 0); + } + + function getIr() private view returns (uint256) { + return irm.computeInterestRateView(address(1), 0, 0); + } +} diff --git a/test/Lens/InterestRates.t.sol b/test/Lens/InterestRates.t.sol index 17d55cf4..a54f58c5 100644 --- a/test/Lens/InterestRates.t.sol +++ b/test/Lens/InterestRates.t.sol @@ -9,6 +9,8 @@ import {RPow} from "../../lib/euler-vault-kit/src/EVault/shared/lib/RPow.sol"; import "../../src/Lens/LensTypes.sol"; import {EulerKinkIRMFactory} from "../../src/IRMFactory/EulerKinkIRMFactory.sol"; import {EulerIRMAdaptiveCurveFactory} from "../../src/IRMFactory/EulerIRMAdaptiveCurveFactory.sol"; +import {EulerKinkIRMFactory} from "../../src/IRMFactory/EulerKinkIRMFactory.sol"; +import {EulerIRMAdaptiveCurveFactory} from "../../src/IRMFactory/EulerIRMAdaptiveCurveFactory.sol"; import {AccountLens} from "../../src/Lens/AccountLens.sol"; import {OracleLens} from "../../src/Lens/OracleLens.sol"; import {IRMLens} from "../../src/Lens/IRMLens.sol"; @@ -26,6 +28,8 @@ contract InterestRates is EVaultTestBase { EulerKinkIRMFactory public irmFactory; EulerIRMAdaptiveCurveFactory public irmAdaptiveCurveFactory; + EulerKinkIRMFactory public irmKinkyFactory; + EulerIRMAdaptiveCurveFactory public irmFixedCyclicalBinaryFactory; AccountLens public accountLens; OracleLens public oracleLens; IRMLens public irmLens; @@ -39,9 +43,16 @@ contract InterestRates is EVaultTestBase { irmFactory = new EulerKinkIRMFactory(); irmAdaptiveCurveFactory = new EulerIRMAdaptiveCurveFactory(); + irmKinkyFactory = new EulerKinkIRMFactory(); + irmFixedCyclicalBinaryFactory = new EulerIRMAdaptiveCurveFactory(); accountLens = new AccountLens(); oracleLens = new OracleLens(address(0)); - irmLens = new IRMLens(address(irmFactory), address(irmAdaptiveCurveFactory)); + irmLens = new IRMLens( + address(irmFactory), + address(irmAdaptiveCurveFactory), + address(irmKinkyFactory), + address(irmFixedCyclicalBinaryFactory) + ); utilsLens = new UtilsLens(address(factory), address(oracleLens)); vaultLens = new VaultLens(address(oracleLens), address(utilsLens), address(irmLens));