From a0197e772fcd0219d2f9952df693b69e06e11b98 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Mon, 24 Jun 2024 02:48:13 -0400 Subject: [PATCH 01/12] wip IGP-29 --- contracts/payloads/IGP29/PayloadIGP29.sol | 466 ++++++++++++++++++++++ 1 file changed, 466 insertions(+) create mode 100644 contracts/payloads/IGP29/PayloadIGP29.sol diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol new file mode 100644 index 0000000..7f93ecb --- /dev/null +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -0,0 +1,466 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +interface IGovernorBravo { + function _acceptAdmin() external; + + function _setVotingDelay(uint newVotingDelay) external; + + function _setVotingPeriod(uint newVotingPeriod) external; + + function _acceptAdminOnTimelock() external; + + function _setImplementation(address implementation_) external; + + function propose( + address[] memory targets, + uint[] memory values, + string[] memory signatures, + bytes[] memory calldatas, + string memory description + ) external returns (uint); + + function admin() external view returns (address); + + function pendingAdmin() external view returns (address); + + function timelock() external view returns (address); + + function votingDelay() external view returns (uint256); + + function votingPeriod() external view returns (uint256); +} + +interface ITimelock { + function acceptAdmin() external; + + function setDelay(uint delay_) external; + + function setPendingAdmin(address pendingAdmin_) external; + + function queueTransaction( + address target, + uint value, + string memory signature, + bytes memory data, + uint eta + ) external returns (bytes32); + + function executeTransaction( + address target, + uint value, + string memory signature, + bytes memory data, + uint eta + ) external payable returns (bytes memory); + + function pendingAdmin() external view returns (address); + + function admin() external view returns (address); + + function delay() external view returns (uint256); +} + +interface AdminModuleStructs { + struct AddressBool { + address addr; + bool value; + } + + struct AddressUint256 { + address addr; + uint256 value; + } + + struct RateDataV1Params { + address token; + uint256 kink; + uint256 rateAtUtilizationZero; + uint256 rateAtUtilizationKink; + uint256 rateAtUtilizationMax; + } + + struct RateDataV2Params { + address token; + uint256 kink1; + uint256 kink2; + uint256 rateAtUtilizationZero; + uint256 rateAtUtilizationKink1; + uint256 rateAtUtilizationKink2; + uint256 rateAtUtilizationMax; + } + + struct TokenConfig { + address token; + uint256 fee; + uint256 threshold; + uint256 maxUtilization; + } + + struct UserSupplyConfig { + address user; + address token; + uint8 mode; + uint256 expandPercent; + uint256 expandDuration; + uint256 baseWithdrawalLimit; + } + + struct UserBorrowConfig { + address user; + address token; + uint8 mode; + uint256 expandPercent; + uint256 expandDuration; + uint256 baseDebtCeiling; + uint256 maxDebtCeiling; + } +} + +interface IProxy { + function setAdmin(address newAdmin_) external; + + function setDummyImplementation(address newDummyImplementation_) external; + + function addImplementation( + address implementation_, + bytes4[] calldata sigs_ + ) external; + + function removeImplementation(address implementation_) external; + + function getAdmin() external view returns (address); + + function getDummyImplementation() external view returns (address); + + function getImplementationSigs( + address impl_ + ) external view returns (bytes4[] memory); + + function getSigsImplementation(bytes4 sig_) external view returns (address); + + function readFromStorage( + bytes32 slot_ + ) external view returns (uint256 result_); +} + +interface IFluidLiquidityAdmin { + /// @notice adds/removes auths. Auths generally could be contracts which can have restricted actions defined on contract. + /// auths can be helpful in reducing governance overhead where it's not needed. + /// @param authsStatus_ array of structs setting allowed status for an address. + /// status true => add auth, false => remove auth + function updateAuths( + AdminModuleStructs.AddressBool[] calldata authsStatus_ + ) external; + + /// @notice adds/removes guardians. Only callable by Governance. + /// @param guardiansStatus_ array of structs setting allowed status for an address. + /// status true => add guardian, false => remove guardian + function updateGuardians( + AdminModuleStructs.AddressBool[] calldata guardiansStatus_ + ) external; + + /// @notice changes the revenue collector address (contract that is sent revenue). Only callable by Governance. + /// @param revenueCollector_ new revenue collector address + function updateRevenueCollector(address revenueCollector_) external; + + /// @notice changes current status, e.g. for pausing or unpausing all user operations. Only callable by Auths. + /// @param newStatus_ new status + /// status = 2 -> pause, status = 1 -> resume. + function changeStatus(uint256 newStatus_) external; + + /// @notice update tokens rate data version 1. Only callable by Auths. + /// @param tokensRateData_ array of RateDataV1Params with rate data to set for each token + function updateRateDataV1s( + AdminModuleStructs.RateDataV1Params[] calldata tokensRateData_ + ) external; + + /// @notice update tokens rate data version 2. Only callable by Auths. + /// @param tokensRateData_ array of RateDataV2Params with rate data to set for each token + function updateRateDataV2s( + AdminModuleStructs.RateDataV2Params[] calldata tokensRateData_ + ) external; + + /// @notice updates token configs: fee charge on borrowers interest & storage update utilization threshold. + /// Only callable by Auths. + /// @param tokenConfigs_ contains token address, fee & utilization threshold + function updateTokenConfigs( + AdminModuleStructs.TokenConfig[] calldata tokenConfigs_ + ) external; + + /// @notice updates user classes: 0 is for new protocols, 1 is for established protocols. + /// Only callable by Auths. + /// @param userClasses_ struct array of uint256 value to assign for each user address + function updateUserClasses( + AdminModuleStructs.AddressUint256[] calldata userClasses_ + ) external; + + /// @notice sets user supply configs per token basis. Eg: with interest or interest-free and automated limits. + /// Only callable by Auths. + /// @param userSupplyConfigs_ struct array containing user supply config, see `UserSupplyConfig` struct for more info + function updateUserSupplyConfigs( + AdminModuleStructs.UserSupplyConfig[] memory userSupplyConfigs_ + ) external; + + /// @notice setting user borrow configs per token basis. Eg: with interest or interest-free and automated limits. + /// Only callable by Auths. + /// @param userBorrowConfigs_ struct array containing user borrow config, see `UserBorrowConfig` struct for more info + function updateUserBorrowConfigs( + AdminModuleStructs.UserBorrowConfig[] memory userBorrowConfigs_ + ) external; + + /// @notice pause operations for a particular user in class 0 (class 1 users can't be paused by guardians). + /// Only callable by Guardians. + /// @param user_ address of user to pause operations for + /// @param supplyTokens_ token addresses to pause withdrawals for + /// @param borrowTokens_ token addresses to pause borrowings for + function pauseUser( + address user_, + address[] calldata supplyTokens_, + address[] calldata borrowTokens_ + ) external; + + /// @notice unpause operations for a particular user in class 0 (class 1 users can't be paused by guardians). + /// Only callable by Guardians. + /// @param user_ address of user to unpause operations for + /// @param supplyTokens_ token addresses to unpause withdrawals for + /// @param borrowTokens_ token addresses to unpause borrowings for + function unpauseUser( + address user_, + address[] calldata supplyTokens_, + address[] calldata borrowTokens_ + ) external; + + /// @notice collects revenue for tokens to configured revenueCollector address. + /// @param tokens_ array of tokens to collect revenue for + /// @dev Note that this can revert if token balance is < revenueAmount (utilization > 100%) + function collectRevenue(address[] calldata tokens_) external; + + /// @notice gets the current updated exchange prices for n tokens and updates all prices, rates related data in storage. + /// @param tokens_ tokens to update exchange prices for + /// @return supplyExchangePrices_ new supply rates of overall system for each token + /// @return borrowExchangePrices_ new borrow rates of overall system for each token + function updateExchangePrices( + address[] calldata tokens_ + ) + external + returns ( + uint256[] memory supplyExchangePrices_, + uint256[] memory borrowExchangePrices_ + ); +} + +interface IFluidVaultT1 { + /// @notice updates the Vault oracle to `newOracle_`. Must implement the FluidOracle interface. + function updateOracle(address newOracle_) external; + + /// @notice updates the all Vault core settings according to input params. + /// All input values are expected in 1e2 (1% = 100, 100% = 10_000). + function updateCoreSettings( + uint256 supplyRateMagnifier_, + uint256 borrowRateMagnifier_, + uint256 collateralFactor_, + uint256 liquidationThreshold_, + uint256 liquidationMaxLimit_, + uint256 withdrawGap_, + uint256 liquidationPenalty_, + uint256 borrowFee_ + ) external; + + /// @notice updates the allowed rebalancer to `newRebalancer_`. + function updateRebalancer(address newRebalancer_) external; + + /// @notice updates the supply rate magnifier to `supplyRateMagnifier_`. Input in 1e2 (1% = 100, 100% = 10_000). + function updateSupplyRateMagnifier(uint supplyRateMagnifier_) external; + + /// @notice updates the collateral factor to `collateralFactor_`. Input in 1e2 (1% = 100, 100% = 10_000). + function updateCollateralFactor(uint collateralFactor_) external; +} + +interface IFluidVaultT1Factory { + function deployVault( + address vaultDeploymentLogic_, + bytes calldata vaultDeploymentData_ + ) external returns (address vault_); + + function setVaultAuth( + address vault_, + address vaultAuth_, + bool allowed_ + ) external; +} + +interface IFluidVaultT1DeploymentLogic { + function vaultT1(address supplyToken_, address borrowToken_) external; +} + +contract PayloadIGP28 { + uint256 public constant PROPOSAL_ID = 28; + + address public constant PROPOSER = + 0xA45f7bD6A5Ff45D31aaCE6bCD3d426D9328cea01; + + address public constant PROPOSER_AVO_MULTISIG = + 0x059A94A72951c0ae1cc1CE3BF0dB52421bbE8210; + + address public constant PROPOSER_AVO_MULTISIG_2 = + 0x9efdE135CA4832AbF0408c44c6f5f370eB0f35e8; + + IGovernorBravo public constant GOVERNOR = + IGovernorBravo(0x0204Cd037B2ec03605CFdFe482D8e257C765fA1B); + ITimelock public immutable TIMELOCK = + ITimelock(0x2386DC45AdDed673317eF068992F19421B481F4c); + + address public immutable ADDRESS_THIS; + + address public constant TEAM_MULTISIG = + 0x4F6F977aCDD1177DCD81aB83074855EcB9C2D49e; + + IFluidLiquidityAdmin public constant LIQUIDITY = + IFluidLiquidityAdmin(0x52Aa899454998Be5b000Ad077a46Bbe360F4e497); + IFluidVaultT1Factory public constant VAULT_T1_FACTORY = + IFluidVaultT1Factory(0x324c5Dc1fC42c7a4D43d92df1eBA58a54d13Bf2d); + IFluidVaultT1DeploymentLogic public constant VAULT_T1_DEPLOYMENT_LOGIC = + IFluidVaultT1DeploymentLogic( + 0x2Cc710218F2e3a82CcC77Cc4B3B93Ee6Ba9451CD + ); + + address public constant ETH_ADDRESS = + 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; + address public constant wstETH_ADDRESS = + 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0; + address public constant weETH_ADDRESS = + 0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee; + + address public constant PT_sUSDe_ADDRESS = + 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497; // TODO + + address public constant sUSDe_ADDRESS = + 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497; + address public constant USDC_ADDRESS = + 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address public constant USDT_ADDRESS = + 0xdAC17F958D2ee523a2206206994597C13D831ec7; + + constructor() { + ADDRESS_THIS = address(this); + } + + function propose(string memory description) external { + require( + msg.sender == PROPOSER || + msg.sender == TEAM_MULTISIG || + address(this) == PROPOSER_AVO_MULTISIG || + address(this) == PROPOSER_AVO_MULTISIG_2, + "msg.sender-not-allowed" + ); + + uint256 totalActions = 1; + address[] memory targets = new address[](totalActions); + uint256[] memory values = new uint256[](totalActions); + string[] memory signatures = new string[](totalActions); + bytes[] memory calldatas = new bytes[](totalActions); + + // Action 1: call executePayload on timelock contract to execute payload related to Fluid + targets[0] = address(TIMELOCK); + values[0] = 0; + signatures[0] = "executePayload(address,string,bytes)"; + calldatas[0] = abi.encode(ADDRESS_THIS, "execute()", abi.encode()); + + uint256 proposedId = GOVERNOR.propose( + targets, + values, + signatures, + calldatas, + description + ); + + require(proposedId == PROPOSAL_ID, "PROPOSAL_IS_NOT_SAME"); + } + + function execute() external { + require(address(this) == address(TIMELOCK), "not-valid-caller"); + + } + + function verifyProposal() external view {} + + /***********************************| + | Proposal Payload Actions | + |__________________________________*/ + + function deploy_PT_sUSDe_USDC_VAULT() internal { + // Deploy PT_sUSDe/USDC vault. + address vault_ = VAULT_T1_FACTORY.deployVault( + address(VAULT_T1_DEPLOYMENT_LOGIC), + abi.encodeWithSelector( + IFluidVaultT1DeploymentLogic.vaultT1.selector, + PT_sUSDe_ADDRESS, // PT_sUSDe, + USDC_ADDRESS // USDC + ) + ); + + // Set user supply config for the vault on Liquidity Layer. + { + AdminModuleStructs.UserSupplyConfig[] + memory configs_ = new AdminModuleStructs.UserSupplyConfig[](1); + + configs_[0] = AdminModuleStructs.UserSupplyConfig({ + user: address(vault_), + token: PT_sUSDe_ADDRESS, + mode: 1, + expandPercent: 25 * 1e2, // 25% + expandDuration: 12 hours, + baseWithdrawalLimit: 2_500 * 1e18 // 2_500 PT_sUSDe + }); + + LIQUIDITY.updateUserSupplyConfigs(configs_); + } + + // Set user borrow config for the vault on Liquidity Layer. + { + AdminModuleStructs.UserBorrowConfig[] + memory configs_ = new AdminModuleStructs.UserBorrowConfig[](1); + + configs_[0] = AdminModuleStructs.UserBorrowConfig({ + user: address(vault_), + token: USDC_ADDRESS, + mode: 1, + expandPercent: 20 * 1e2, // 20% + expandDuration: 12 hours, + baseDebtCeiling: 7_500_000 * 1e6, // 7.5M + maxDebtCeiling: 20_000_000 * 1e6 // 20M + }); + + LIQUIDITY.updateUserBorrowConfigs(configs_); + } + + // Update core settings on PT_sUSDe/USDC vault. + { + IFluidVaultT1(vault_).updateCoreSettings( + 100 * 1e2, // 1x supplyRateMagnifier + 100 * 1e2, // 1x borrowRateMagnifier + 75 * 1e2, // 75% collateralFactor + 80 * 1e2, // 80% liquidationThreshold + 90 * 1e2, // 90% liquidationMaxLimit + 5 * 1e2, // 5% withdrawGap + 4 * 1e2, // 4% liquidationPenalty + 0 // 0% borrowFee + ); + } + + // Update oracle on PT_sUSDe/USDC vault. + { + IFluidVaultT1(vault_).updateOracle( + 0x64D9cd2B6a63100d8305ca8e3b46E26d5a38951f + ); + } + + // Update rebalancer on weETH/USDC vault. + { + IFluidVaultT1(vault_).updateRebalancer( + 0x264786EF916af64a1DB19F513F24a3681734ce92 + ); + } + } +} From bd27d2241de10e82a724204a0ffbe4619e4c53b8 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Mon, 24 Jun 2024 12:21:22 -0400 Subject: [PATCH 02/12] WIP --- contracts/payloads/IGP29/PayloadIGP29.sol | 87 ++++++++++++++++++----- 1 file changed, 70 insertions(+), 17 deletions(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index 7f93ecb..4bc3d99 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -333,7 +333,7 @@ contract PayloadIGP28 { 0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee; address public constant PT_sUSDe_ADDRESS = - 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497; // TODO + 0x6c9f097e044506712B58EAC670c9a5fd4BCceF13; address public constant sUSDe_ADDRESS = 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497; @@ -381,6 +381,12 @@ contract PayloadIGP28 { function execute() external { require(address(this) == address(TIMELOCK), "not-valid-caller"); + /// Action 1: Set PT_sUSDe token config and market rate curve on liquidity. + action1(); + + /// Action 2: Update PT_sUSDe/USDC and PT_sUSDe/USDT vaults. + action2(); + } function verifyProposal() external view {} @@ -389,14 +395,61 @@ contract PayloadIGP28 { | Proposal Payload Actions | |__________________________________*/ - function deploy_PT_sUSDe_USDC_VAULT() internal { + /// @notice Action 1: Set PT_sUSDe token config and market rate curve on liquidity. + function action1() internal { + { + AdminModuleStructs.TokenConfig[] + memory params_ = new AdminModuleStructs.TokenConfig[](1); + + params_[0] = AdminModuleStructs.TokenConfig({ + token: PT_sUSDe_ADDRESS, // PT_sUSDe + threshold: 0.3 * 1e2, // 0.3 + fee: 10 * 1e2, // 10% + maxUtilization: 0 + }); + + LIQUIDITY.updateTokenConfigs(params_); + } + + { + AdminModuleStructs.RateDataV2Params[] + memory params_ = new AdminModuleStructs.RateDataV2Params[](1); + + params_[0] = AdminModuleStructs.RateDataV2Params({ + token: PT_sUSDe_ADDRESS, // PT_sUSDe + kink1: 50 * 1e2, // 50% + kink2: 80 * 1e2, // 80% + rateAtUtilizationZero: 0, // 0% + rateAtUtilizationKink1: 20 * 1e2, // 20% + rateAtUtilizationKink2: 40 * 1e2, // 40% + rateAtUtilizationMax: 100 * 1e2 // 100% + }); + + LIQUIDITY.updateRateDataV2s(params_); + } + } + + /// @notice Action 2: Update PT_sUSDe/USDC and PT_sUSDe/USDT vaults. + function action2() internal { // Deploy PT_sUSDe/USDC vault. + deploy_PT_sUSDe_VAULT(USDC_ADDRESS); + + // Deploy PT_sUSDe/USDT vault. + deploy_PT_sUSDe_VAULT(USDT_ADDRESS); + } + + /***********************************| + | Proposal Payload Helpers | + |__________________________________*/ + + function deploy_PT_sUSDe_VAULT(address debtToken) internal { + // Deploy PT_sUSDe based vault. address vault_ = VAULT_T1_FACTORY.deployVault( address(VAULT_T1_DEPLOYMENT_LOGIC), abi.encodeWithSelector( IFluidVaultT1DeploymentLogic.vaultT1.selector, PT_sUSDe_ADDRESS, // PT_sUSDe, - USDC_ADDRESS // USDC + debtToken // USDC or USDT ) ); @@ -411,7 +464,7 @@ contract PayloadIGP28 { mode: 1, expandPercent: 25 * 1e2, // 25% expandDuration: 12 hours, - baseWithdrawalLimit: 2_500 * 1e18 // 2_500 PT_sUSDe + baseWithdrawalLimit: 5_000_000 * 1e18 // 5M PT_sUSDe }); LIQUIDITY.updateUserSupplyConfigs(configs_); @@ -424,39 +477,39 @@ contract PayloadIGP28 { configs_[0] = AdminModuleStructs.UserBorrowConfig({ user: address(vault_), - token: USDC_ADDRESS, + token: debtToken, mode: 1, expandPercent: 20 * 1e2, // 20% expandDuration: 12 hours, baseDebtCeiling: 7_500_000 * 1e6, // 7.5M - maxDebtCeiling: 20_000_000 * 1e6 // 20M + maxDebtCeiling: 10_000_000 * 1e6 // 10M }); LIQUIDITY.updateUserBorrowConfigs(configs_); } - // Update core settings on PT_sUSDe/USDC vault. + // Update core settings on vault. { IFluidVaultT1(vault_).updateCoreSettings( 100 * 1e2, // 1x supplyRateMagnifier - 100 * 1e2, // 1x borrowRateMagnifier - 75 * 1e2, // 75% collateralFactor - 80 * 1e2, // 80% liquidationThreshold - 90 * 1e2, // 90% liquidationMaxLimit - 5 * 1e2, // 5% withdrawGap - 4 * 1e2, // 4% liquidationPenalty - 0 // 0% borrowFee + 200 * 1e2, // 2x borrowRateMagnifier + 88 * 1e2, // 88% collateralFactor + 90 * 1e2, // 90% liquidationThreshold + 95 * 1e2, // 95% liquidationMaxLimit + 2 * 1e2, // 2% withdrawGap + 5 * 1e2, // 5% liquidationPenalty + 0 // 0% borrowFee ); } - // Update oracle on PT_sUSDe/USDC vault. + // Update oracle on vault. { IFluidVaultT1(vault_).updateOracle( - 0x64D9cd2B6a63100d8305ca8e3b46E26d5a38951f + 0x58455665979fdf24c3Ea8674323326bD99237e12 ); } - // Update rebalancer on weETH/USDC vault. + // Update rebalancer on vault. { IFluidVaultT1(vault_).updateRebalancer( 0x264786EF916af64a1DB19F513F24a3681734ce92 From 55eb0917926ee7a6064c928623c1b060d45cefe0 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Mon, 24 Jun 2024 12:31:03 -0400 Subject: [PATCH 03/12] fix --- contracts/payloads/IGP29/PayloadIGP29.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index 4bc3d99..9d5b483 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -294,8 +294,8 @@ interface IFluidVaultT1DeploymentLogic { function vaultT1(address supplyToken_, address borrowToken_) external; } -contract PayloadIGP28 { - uint256 public constant PROPOSAL_ID = 28; +contract PayloadIGP29 { + uint256 public constant PROPOSAL_ID = 29; address public constant PROPOSER = 0xA45f7bD6A5Ff45D31aaCE6bCD3d426D9328cea01; From e0508f409f71542a8c5d8dac3213fe8d3ccbd601 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Mon, 24 Jun 2024 12:49:02 -0400 Subject: [PATCH 04/12] fix --- contracts/payloads/IGP29/PayloadIGP29.sol | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index 9d5b483..455efb2 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -397,20 +397,6 @@ contract PayloadIGP29 { /// @notice Action 1: Set PT_sUSDe token config and market rate curve on liquidity. function action1() internal { - { - AdminModuleStructs.TokenConfig[] - memory params_ = new AdminModuleStructs.TokenConfig[](1); - - params_[0] = AdminModuleStructs.TokenConfig({ - token: PT_sUSDe_ADDRESS, // PT_sUSDe - threshold: 0.3 * 1e2, // 0.3 - fee: 10 * 1e2, // 10% - maxUtilization: 0 - }); - - LIQUIDITY.updateTokenConfigs(params_); - } - { AdminModuleStructs.RateDataV2Params[] memory params_ = new AdminModuleStructs.RateDataV2Params[](1); @@ -427,6 +413,21 @@ contract PayloadIGP29 { LIQUIDITY.updateRateDataV2s(params_); } + + { + AdminModuleStructs.TokenConfig[] + memory params_ = new AdminModuleStructs.TokenConfig[](1); + + params_[0] = AdminModuleStructs.TokenConfig({ + token: PT_sUSDe_ADDRESS, // PT_sUSDe + threshold: 0.3 * 1e2, // 0.3 + fee: 10 * 1e2, // 10% + maxUtilization: 0 + }); + + LIQUIDITY.updateTokenConfigs(params_); + } + } /// @notice Action 2: Update PT_sUSDe/USDC and PT_sUSDe/USDT vaults. @@ -497,7 +498,7 @@ contract PayloadIGP29 { 90 * 1e2, // 90% liquidationThreshold 95 * 1e2, // 95% liquidationMaxLimit 2 * 1e2, // 2% withdrawGap - 5 * 1e2, // 5% liquidationPenalty + 4.5 * 1e2, // 5% liquidationPenalty 0 // 0% borrowFee ); } From 16e735b8a44884427b5acac08c7fdaa43fd8339e Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Mon, 24 Jun 2024 13:18:41 -0400 Subject: [PATCH 05/12] fix --- contracts/payloads/IGP29/PayloadIGP29.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index 455efb2..977c52a 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -295,7 +295,7 @@ interface IFluidVaultT1DeploymentLogic { } contract PayloadIGP29 { - uint256 public constant PROPOSAL_ID = 29; + uint256 public constant PROPOSAL_ID = 28; address public constant PROPOSER = 0xA45f7bD6A5Ff45D31aaCE6bCD3d426D9328cea01; @@ -496,9 +496,9 @@ contract PayloadIGP29 { 200 * 1e2, // 2x borrowRateMagnifier 88 * 1e2, // 88% collateralFactor 90 * 1e2, // 90% liquidationThreshold - 95 * 1e2, // 95% liquidationMaxLimit + 94 * 1e2, // 94% liquidationMaxLimit 2 * 1e2, // 2% withdrawGap - 4.5 * 1e2, // 5% liquidationPenalty + 4 * 1e2, // 4% liquidationPenalty 0 // 0% borrowFee ); } From 7882974acbf346dc8d28b3f76613c72e4824740a Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Mon, 24 Jun 2024 14:30:46 -0400 Subject: [PATCH 06/12] fix --- contracts/payloads/IGP29/PayloadIGP29.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index 977c52a..ee19714 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -482,8 +482,8 @@ contract PayloadIGP29 { mode: 1, expandPercent: 20 * 1e2, // 20% expandDuration: 12 hours, - baseDebtCeiling: 7_500_000 * 1e6, // 7.5M - maxDebtCeiling: 10_000_000 * 1e6 // 10M + baseDebtCeiling: 7_125_000 * 1e6, // ~7.125M + maxDebtCeiling: 9_500_000 * 1e6 // 9.5M }); LIQUIDITY.updateUserBorrowConfigs(configs_); From 08d023de64127d2b04b6a886b120e9e29fdcbd49 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Mon, 24 Jun 2024 16:47:51 -0400 Subject: [PATCH 07/12] fix --- contracts/payloads/IGP29/PayloadIGP29.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index ee19714..b7b6d53 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -295,7 +295,7 @@ interface IFluidVaultT1DeploymentLogic { } contract PayloadIGP29 { - uint256 public constant PROPOSAL_ID = 28; + uint256 public constant PROPOSAL_ID = 29; address public constant PROPOSER = 0xA45f7bD6A5Ff45D31aaCE6bCD3d426D9328cea01; From 2b4ef5f76ea11a2bec1df41b997ac0038769cd20 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Sat, 29 Jun 2024 12:42:06 -0400 Subject: [PATCH 08/12] update --- contracts/payloads/IGP29/PayloadIGP29.sol | 187 +++++++--------------- 1 file changed, 55 insertions(+), 132 deletions(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index b7b6d53..63cf7f0 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -277,21 +277,31 @@ interface IFluidVaultT1 { function updateCollateralFactor(uint collateralFactor_) external; } -interface IFluidVaultT1Factory { - function deployVault( - address vaultDeploymentLogic_, - bytes calldata vaultDeploymentData_ - ) external returns (address vault_); +interface IFluidReserveContract { + function isRebalancer(address user) external returns (bool); - function setVaultAuth( - address vault_, - address vaultAuth_, - bool allowed_ + function rebalanceFToken(address protocol_) external; + + function rebalanceVault(address protocol_) external; + + function transferFunds(address token_) external; + + function getProtocolTokens(address protocol_) external; + + function updateAuth(address auth_, bool isAuth_) external; + + function updateRebalancer(address rebalancer_, bool isRebalancer_) external; + + function approve( + address[] memory protocols_, + address[] memory tokens_, + uint256[] memory amounts_ ) external; -} -interface IFluidVaultT1DeploymentLogic { - function vaultT1(address supplyToken_, address borrowToken_) external; + function revoke( + address[] memory protocols_, + address[] memory tokens_ + ) external; } contract PayloadIGP29 { @@ -318,12 +328,8 @@ contract PayloadIGP29 { IFluidLiquidityAdmin public constant LIQUIDITY = IFluidLiquidityAdmin(0x52Aa899454998Be5b000Ad077a46Bbe360F4e497); - IFluidVaultT1Factory public constant VAULT_T1_FACTORY = - IFluidVaultT1Factory(0x324c5Dc1fC42c7a4D43d92df1eBA58a54d13Bf2d); - IFluidVaultT1DeploymentLogic public constant VAULT_T1_DEPLOYMENT_LOGIC = - IFluidVaultT1DeploymentLogic( - 0x2Cc710218F2e3a82CcC77Cc4B3B93Ee6Ba9451CD - ); + IFluidReserveContract public constant FLUID_RESERVE = + IFluidReserveContract(0x264786EF916af64a1DB19F513F24a3681734ce92); address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; @@ -332,8 +338,8 @@ contract PayloadIGP29 { address public constant weETH_ADDRESS = 0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee; - address public constant PT_sUSDe_ADDRESS = - 0x6c9f097e044506712B58EAC670c9a5fd4BCceF13; + address public constant F_USDT = 0x5C20B550819128074FD538Edf79791733ccEdd18; + address public constant F_USDC = 0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33; address public constant sUSDe_ADDRESS = 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497; @@ -381,10 +387,10 @@ contract PayloadIGP29 { function execute() external { require(address(this) == address(TIMELOCK), "not-valid-caller"); - /// Action 1: Set PT_sUSDe token config and market rate curve on liquidity. + /// Action 1: Approve fUSDC and fUSDT protocols to spend the reserves tokens action1(); - /// Action 2: Update PT_sUSDe/USDC and PT_sUSDe/USDT vaults. + /// Action 2: Add config handler on liquidity layer for sUSDe/USDC & sUSDe/USDT vault. action2(); } @@ -395,126 +401,43 @@ contract PayloadIGP29 { | Proposal Payload Actions | |__________________________________*/ - /// @notice Action 1: Set PT_sUSDe token config and market rate curve on liquidity. + /// @notice Action 1: Approve fUSDC and fUSDT protocols to spend the reserves tokens function action1() internal { - { - AdminModuleStructs.RateDataV2Params[] - memory params_ = new AdminModuleStructs.RateDataV2Params[](1); + address[] memory protocols = new address[](2); + address[] memory tokens = new address[](2); + uint256[] memory amounts = new uint256[](2); - params_[0] = AdminModuleStructs.RateDataV2Params({ - token: PT_sUSDe_ADDRESS, // PT_sUSDe - kink1: 50 * 1e2, // 50% - kink2: 80 * 1e2, // 80% - rateAtUtilizationZero: 0, // 0% - rateAtUtilizationKink1: 20 * 1e2, // 20% - rateAtUtilizationKink2: 40 * 1e2, // 40% - rateAtUtilizationMax: 100 * 1e2 // 100% - }); + // fUSDC + protocols[0] = F_USDC; + tokens[0] = USDC_ADDRESS; + amounts[0] = 290_000 * 1e6; // 290k USDC - LIQUIDITY.updateRateDataV2s(params_); - } - - { - AdminModuleStructs.TokenConfig[] - memory params_ = new AdminModuleStructs.TokenConfig[](1); - - params_[0] = AdminModuleStructs.TokenConfig({ - token: PT_sUSDe_ADDRESS, // PT_sUSDe - threshold: 0.3 * 1e2, // 0.3 - fee: 10 * 1e2, // 10% - maxUtilization: 0 - }); - - LIQUIDITY.updateTokenConfigs(params_); - } + // fUSDT + protocols[1] = F_USDT; + tokens[1] = USDT_ADDRESS; + amounts[1] = 290_000 * 1e6; // 290k USDT + FLUID_RESERVE.approve(protocols, tokens, amounts); } - /// @notice Action 2: Update PT_sUSDe/USDC and PT_sUSDe/USDT vaults. + /// @notice Action 2: Add config handler on liquidity layer for sUSDe/USDC & sUSDe/USDT vault. function action2() internal { - // Deploy PT_sUSDe/USDC vault. - deploy_PT_sUSDe_VAULT(USDC_ADDRESS); + address VAULT_sUSDe_USDC_CONFIG_HANDLER = address(0xa7C805988f04f0e841504761E5aa8387600e430b); + address VAULT_sUSDe_USDT_CONFIG_HANDLER = address(0x7607968F40d7Ac4Ef39E809F29fADDe34C00A0A6); - // Deploy PT_sUSDe/USDT vault. - deploy_PT_sUSDe_VAULT(USDT_ADDRESS); - } + AdminModuleStructs.AddressBool[] + memory configs_ = new AdminModuleStructs.AddressBool[](1); - /***********************************| - | Proposal Payload Helpers | - |__________________________________*/ + configs_[0] = AdminModuleStructs.AddressBool({ + addr: address(VAULT_sUSDe_USDC_CONFIG_HANDLER), + value: true + }); - function deploy_PT_sUSDe_VAULT(address debtToken) internal { - // Deploy PT_sUSDe based vault. - address vault_ = VAULT_T1_FACTORY.deployVault( - address(VAULT_T1_DEPLOYMENT_LOGIC), - abi.encodeWithSelector( - IFluidVaultT1DeploymentLogic.vaultT1.selector, - PT_sUSDe_ADDRESS, // PT_sUSDe, - debtToken // USDC or USDT - ) - ); + configs_[1] = AdminModuleStructs.AddressBool({ + addr: address(VAULT_sUSDe_USDT_CONFIG_HANDLER), + value: true + }); - // Set user supply config for the vault on Liquidity Layer. - { - AdminModuleStructs.UserSupplyConfig[] - memory configs_ = new AdminModuleStructs.UserSupplyConfig[](1); - - configs_[0] = AdminModuleStructs.UserSupplyConfig({ - user: address(vault_), - token: PT_sUSDe_ADDRESS, - mode: 1, - expandPercent: 25 * 1e2, // 25% - expandDuration: 12 hours, - baseWithdrawalLimit: 5_000_000 * 1e18 // 5M PT_sUSDe - }); - - LIQUIDITY.updateUserSupplyConfigs(configs_); - } - - // Set user borrow config for the vault on Liquidity Layer. - { - AdminModuleStructs.UserBorrowConfig[] - memory configs_ = new AdminModuleStructs.UserBorrowConfig[](1); - - configs_[0] = AdminModuleStructs.UserBorrowConfig({ - user: address(vault_), - token: debtToken, - mode: 1, - expandPercent: 20 * 1e2, // 20% - expandDuration: 12 hours, - baseDebtCeiling: 7_125_000 * 1e6, // ~7.125M - maxDebtCeiling: 9_500_000 * 1e6 // 9.5M - }); - - LIQUIDITY.updateUserBorrowConfigs(configs_); - } - - // Update core settings on vault. - { - IFluidVaultT1(vault_).updateCoreSettings( - 100 * 1e2, // 1x supplyRateMagnifier - 200 * 1e2, // 2x borrowRateMagnifier - 88 * 1e2, // 88% collateralFactor - 90 * 1e2, // 90% liquidationThreshold - 94 * 1e2, // 94% liquidationMaxLimit - 2 * 1e2, // 2% withdrawGap - 4 * 1e2, // 4% liquidationPenalty - 0 // 0% borrowFee - ); - } - - // Update oracle on vault. - { - IFluidVaultT1(vault_).updateOracle( - 0x58455665979fdf24c3Ea8674323326bD99237e12 - ); - } - - // Update rebalancer on vault. - { - IFluidVaultT1(vault_).updateRebalancer( - 0x264786EF916af64a1DB19F513F24a3681734ce92 - ); - } + LIQUIDITY.updateAuths(configs_); } } From 2860e55cb38488229a0acee579040cb843db1594 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Sat, 29 Jun 2024 12:46:23 -0400 Subject: [PATCH 09/12] wip --- contracts/payloads/IGP29/PayloadIGP29.sol | 42 ++++++++++++++++++----- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index 63cf7f0..f0ca020 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -304,6 +304,19 @@ interface IFluidReserveContract { ) external; } +interface IDSAV2 { + function cast( + string[] memory _targetNames, + bytes[] memory _datas, + address _origin + ) + external + payable + returns (bytes32); + + function isAuth(address user) external view returns (bool); +} + contract PayloadIGP29 { uint256 public constant PROPOSAL_ID = 29; @@ -331,18 +344,11 @@ contract PayloadIGP29 { IFluidReserveContract public constant FLUID_RESERVE = IFluidReserveContract(0x264786EF916af64a1DB19F513F24a3681734ce92); - address public constant ETH_ADDRESS = - 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; - address public constant wstETH_ADDRESS = - 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0; - address public constant weETH_ADDRESS = - 0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee; + IDSAV2 public constant TREASURY = IDSAV2(0x28849D2b63fA8D361e5fc15cB8aBB13019884d09); address public constant F_USDT = 0x5C20B550819128074FD538Edf79791733ccEdd18; address public constant F_USDC = 0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33; - address public constant sUSDe_ADDRESS = - 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497; address public constant USDC_ADDRESS = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address public constant USDT_ADDRESS = @@ -393,6 +399,8 @@ contract PayloadIGP29 { /// Action 2: Add config handler on liquidity layer for sUSDe/USDC & sUSDe/USDT vault. action2(); + /// Action 3: call cast() - transfer 100 stETH to Team Multisig from treasury. + action3(); } function verifyProposal() external view {} @@ -440,4 +448,22 @@ contract PayloadIGP29 { LIQUIDITY.updateAuths(configs_); } + + /// @notice Action 3: call cast() - transfer 100 stETH to Team Multisig from treasury. + function action3() internal { + string[] memory targets = new string[](2); + bytes[] memory encodedSpells = new bytes[](2); + + string memory withdrawSignature = "withdraw(address,uint256,address,uint256,uint256)"; + + // Spell 1: Transfer stETH + { + address STETH_ADDRESS = 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84; + uint256 STETH_AMOUNT = 100 * 1e18; // 100 stETH + targets[0] = "BASIC-A"; + encodedSpells[0] = abi.encodeWithSignature(withdrawSignature, STETH_ADDRESS, STETH_AMOUNT, TEAM_MULTISIG, 0, 0); + } + + IDSAV2(TREASURY).cast(targets, encodedSpells, address(this)); + } } From 4b06d7ef9775b942e16e4ae1134c747024a10c42 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Sat, 29 Jun 2024 12:46:45 -0400 Subject: [PATCH 10/12] fix --- contracts/payloads/IGP29/PayloadIGP29.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index f0ca020..a297ac2 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -451,8 +451,8 @@ contract PayloadIGP29 { /// @notice Action 3: call cast() - transfer 100 stETH to Team Multisig from treasury. function action3() internal { - string[] memory targets = new string[](2); - bytes[] memory encodedSpells = new bytes[](2); + string[] memory targets = new string[](1); + bytes[] memory encodedSpells = new bytes[](1); string memory withdrawSignature = "withdraw(address,uint256,address,uint256,uint256)"; From d2f56bef7730fdcc4ded8886bd838aae21c76483 Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Sat, 29 Jun 2024 12:46:57 -0400 Subject: [PATCH 11/12] fix --- contracts/payloads/IGP29/PayloadIGP29.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index a297ac2..19a290e 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -434,7 +434,7 @@ contract PayloadIGP29 { address VAULT_sUSDe_USDT_CONFIG_HANDLER = address(0x7607968F40d7Ac4Ef39E809F29fADDe34C00A0A6); AdminModuleStructs.AddressBool[] - memory configs_ = new AdminModuleStructs.AddressBool[](1); + memory configs_ = new AdminModuleStructs.AddressBool[](2); configs_[0] = AdminModuleStructs.AddressBool({ addr: address(VAULT_sUSDe_USDC_CONFIG_HANDLER), From ad0610ac556c877ab84bf4c4371e35658326326b Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Sat, 29 Jun 2024 15:06:31 -0400 Subject: [PATCH 12/12] fix --- contracts/payloads/IGP29/PayloadIGP29.sol | 46 ++++++++++++++++------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/contracts/payloads/IGP29/PayloadIGP29.sol b/contracts/payloads/IGP29/PayloadIGP29.sol index 19a290e..52aa672 100644 --- a/contracts/payloads/IGP29/PayloadIGP29.sol +++ b/contracts/payloads/IGP29/PayloadIGP29.sol @@ -317,6 +317,19 @@ interface IDSAV2 { function isAuth(address user) external view returns (bool); } +interface IFluidVaultT1Factory { + function deployVault( + address vaultDeploymentLogic_, + bytes calldata vaultDeploymentData_ + ) external returns (address vault_); + + function setVaultAuth( + address vault_, + address vaultAuth_, + bool allowed_ + ) external; +} + contract PayloadIGP29 { uint256 public constant PROPOSAL_ID = 29; @@ -343,6 +356,8 @@ contract PayloadIGP29 { IFluidLiquidityAdmin(0x52Aa899454998Be5b000Ad077a46Bbe360F4e497); IFluidReserveContract public constant FLUID_RESERVE = IFluidReserveContract(0x264786EF916af64a1DB19F513F24a3681734ce92); + IFluidVaultT1Factory public constant VAULT_T1_FACTORY = + IFluidVaultT1Factory(0x324c5Dc1fC42c7a4D43d92df1eBA58a54d13Bf2d); IDSAV2 public constant TREASURY = IDSAV2(0x28849D2b63fA8D361e5fc15cB8aBB13019884d09); @@ -430,23 +445,28 @@ contract PayloadIGP29 { /// @notice Action 2: Add config handler on liquidity layer for sUSDe/USDC & sUSDe/USDT vault. function action2() internal { - address VAULT_sUSDe_USDC_CONFIG_HANDLER = address(0xa7C805988f04f0e841504761E5aa8387600e430b); - address VAULT_sUSDe_USDT_CONFIG_HANDLER = address(0x7607968F40d7Ac4Ef39E809F29fADDe34C00A0A6); + { + address VAULT_sUSDe_USDC = address(0x3996464c0fCCa8183e13ea5E5e74375e2c8744Dd); + address VAULT_sUSDe_USDC_CONFIG_HANDLER = address(0xa7C805988f04f0e841504761E5aa8387600e430b); - AdminModuleStructs.AddressBool[] - memory configs_ = new AdminModuleStructs.AddressBool[](2); + VAULT_T1_FACTORY.setVaultAuth( + VAULT_sUSDe_USDC, + VAULT_sUSDe_USDC_CONFIG_HANDLER, + true + ); + } - configs_[0] = AdminModuleStructs.AddressBool({ - addr: address(VAULT_sUSDe_USDC_CONFIG_HANDLER), - value: true - }); + { + address VAULT_sUSDe_USDT = address(0xBc345229C1b52e4c30530C614BB487323BA38Da5); + address VAULT_sUSDe_USDT_CONFIG_HANDLER = address(0x7607968F40d7Ac4Ef39E809F29fADDe34C00A0A6); - configs_[1] = AdminModuleStructs.AddressBool({ - addr: address(VAULT_sUSDe_USDT_CONFIG_HANDLER), - value: true - }); + VAULT_T1_FACTORY.setVaultAuth( + VAULT_sUSDe_USDT, + VAULT_sUSDe_USDT_CONFIG_HANDLER, + true + ); + } - LIQUIDITY.updateAuths(configs_); } /// @notice Action 3: call cast() - transfer 100 stETH to Team Multisig from treasury.