Skip to content

Commit

Permalink
✨ Onboard sUSDe on Lido instance and Enable sUSDe E-mode on Mainnet a…
Browse files Browse the repository at this point in the history
…nd Lido instances (bgd-labs#522)

* 🎉 first generation

* 🐛 fix emode configurations

* ♻️ change emode name

* ✨ update md file

* 🐛 fix compilation errors

* ✅ ran AaveV3Ethereum Tests

* 🔧 update seed amount

* fix: RF & UOpt can't be 0

* fix: forum link

Co-authored-by: Harsh Pandey <[email protected]>

* fix: forum link

Co-authored-by: Harsh Pandey <[email protected]>

* fix: forum link

Co-authored-by: Harsh Pandey <[email protected]>

* fix: forum link

Co-authored-by: Harsh Pandey <[email protected]>

* fix: emode label

Co-authored-by: Harsh Pandey <[email protected]>

* fix: emode label

Co-authored-by: Harsh Pandey <[email protected]>

* fix: update reserve factor with generic value

Co-authored-by: Harsh Pandey <[email protected]>

* fix: snapshot link

Co-authored-by: Harsh Pandey <[email protected]>

* fix: summary

Co-authored-by: Harsh Pandey <[email protected]>

* fix: motivation

Co-authored-by: Harsh Pandey <[email protected]>

* ♻️ fix emode label on Mainnet pool contract

* ♻️ set borrow cap of 1000

* ♻️ set generic params on rates

* 🐛 update diff file 1

* ✅ add new test

* fix: space issue in md file

Co-authored-by: Ian Flexa <[email protected]>

* ✨ remove sUSDe from isolation

* 🐛 add collateral update debt ceiling to 0

* fix: remove borrow update

* ✅ tests passed

* 🐛 fix emode category from 2 to 4

* ✅ update diff

* 🐛 match specs with payload

* fix: borrow rate in md

Co-authored-by: Harsh Pandey <[email protected]>

* fix: slop 1 in md

Co-authored-by: Harsh Pandey <[email protected]>

* fix: slope 2 in md

Co-authored-by: Harsh Pandey <[email protected]>

* 🎨 lint md

---------

Co-authored-by: Rozengarden <[email protected]>
Co-authored-by: Harsh Pandey <[email protected]>
Co-authored-by: Ian Flexa <[email protected]>
  • Loading branch information
4 people authored Nov 13, 2024
1 parent ab30997 commit 5ad1d7f
Show file tree
Hide file tree
Showing 9 changed files with 769 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
## Reserve changes

### Reserves added

#### sUSDe ([0x9D39A5DE30e57443BfF2A8307A4256c8797A3497](https://etherscan.io/address/0x9D39A5DE30e57443BfF2A8307A4256c8797A3497))

| description | value |
| --- | --- |
| decimals | 18 |
| isActive | true |
| isFrozen | false |
| supplyCap | 20,000,000 sUSDe |
| borrowCap | 1,000 sUSDe |
| debtCeiling | 0 $ [0] |
| isSiloed | false |
| isFlashloanable | true |
| oracle | [0xb37aE8aBa6C0C1Bf2c509fc06E11aa4AF29B665A](https://etherscan.io/address/0xb37aE8aBa6C0C1Bf2c509fc06E11aa4AF29B665A) |
| oracleDecimals | 8 |
| oracleDescription | Capped sUSDe / USDe / USD |
| oracleLatestAnswer | 1.11869905 |
| usageAsCollateralEnabled | true |
| ltv | 0.05 % [5] |
| liquidationThreshold | 0.1 % [10] |
| liquidationBonus | 7.5 % |
| liquidationProtocolFee | 10 % [1000] |
| reserveFactor | 10 % [1000] |
| aToken | [0xc2015641564a5914A17CB9A92eC8d8feCfa8f2D0](https://etherscan.io/address/0xc2015641564a5914A17CB9A92eC8d8feCfa8f2D0) |
| aTokenImpl | [0x7F8Fc14D462bdF93c681c1f2Fd615389bF969Fb2](https://etherscan.io/address/0x7F8Fc14D462bdF93c681c1f2Fd615389bF969Fb2) |
| variableDebtToken | [0x2ABbAab3EF4e4A899d39e7EC996b5715E76b399a](https://etherscan.io/address/0x2ABbAab3EF4e4A899d39e7EC996b5715E76b399a) |
| variableDebtTokenImpl | [0x3E59212c34588a63350142EFad594a20C88C2CEd](https://etherscan.io/address/0x3E59212c34588a63350142EFad594a20C88C2CEd) |
| borrowingEnabled | false |
| isBorrowableInIsolation | false |
| interestRateStrategy | [0x8958b1C39269167527821f8c276Ef7504883f2fa](https://etherscan.io/address/0x8958b1C39269167527821f8c276Ef7504883f2fa) |
| aTokenName | Aave Ethereum Lido sUSDe |
| aTokenSymbol | aEthLidosUSDe |
| aTokenUnderlyingBalance | 100 sUSDe [100000000000000000000] |
| id | 5 |
| isPaused | false |
| variableDebtTokenName | Aave Ethereum Lido Variable Debt sUSDe |
| variableDebtTokenSymbol | variableDebtEthLidosUSDe |
| virtualAccountingActive | true |
| virtualBalance | 100 sUSDe [100000000000000000000] |
| optimalUsageRatio | 1 % |
| maxVariableBorrowRate | 3.15 % |
| baseVariableBorrowRate | 0.05 % |
| variableRateSlope1 | 0.1 % |
| variableRateSlope2 | 3 % |
| interestRate | ![ir](https://dash.onaave.com/api/static?variableRateSlope1=1000000000000000000000000&variableRateSlope2=30000000000000000000000000&optimalUsageRatio=10000000000000000000000000&baseVariableBorrowRate=500000000000000000000000&maxVariableBorrowRate=31500000000000000000000000) |


## Emodes changed

### EMode: ETH correlated(id: 1)



### EMode: LRT Stablecoins main(id: 2)



### EMode: LRT wstETH main(id: 3)



### EMode: sUSDe Stablecoins(id: 4)

| description | value before | value after |
| --- | --- | --- |
| eMode.label | - | sUSDe Stablecoins |
| eMode.ltv | - | 90 % |
| eMode.liquidationThreshold | - | 92 % |
| eMode.liquidationBonus | - | 3 % |
| eMode.borrowableBitmap | - | USDS, USDC |
| eMode.collateralBitmap | - | sUSDe |


## Raw diff

```json
{
"eModes": {
"4": {
"from": null,
"to": {
"borrowableBitmap": 12,
"collateralBitmap": 32,
"eModeCategory": 4,
"label": "sUSDe Stablecoins",
"liquidationBonus": 10300,
"liquidationThreshold": 9200,
"ltv": 9000
}
}
},
"reserves": {
"0x9D39A5DE30e57443BfF2A8307A4256c8797A3497": {
"from": null,
"to": {
"aToken": "0xc2015641564a5914A17CB9A92eC8d8feCfa8f2D0",
"aTokenImpl": "0x7F8Fc14D462bdF93c681c1f2Fd615389bF969Fb2",
"aTokenName": "Aave Ethereum Lido sUSDe",
"aTokenSymbol": "aEthLidosUSDe",
"aTokenUnderlyingBalance": "100000000000000000000",
"borrowCap": 1000,
"borrowingEnabled": false,
"debtCeiling": 0,
"decimals": 18,
"id": 5,
"interestRateStrategy": "0x8958b1C39269167527821f8c276Ef7504883f2fa",
"isActive": true,
"isBorrowableInIsolation": false,
"isFlashloanable": true,
"isFrozen": false,
"isPaused": false,
"isSiloed": false,
"liquidationBonus": 10750,
"liquidationProtocolFee": 1000,
"liquidationThreshold": 10,
"ltv": 5,
"oracle": "0xb37aE8aBa6C0C1Bf2c509fc06E11aa4AF29B665A",
"oracleDecimals": 8,
"oracleDescription": "Capped sUSDe / USDe / USD",
"oracleLatestAnswer": 111869905,
"reserveFactor": 1000,
"supplyCap": 20000000,
"symbol": "sUSDe",
"underlying": "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497",
"usageAsCollateralEnabled": true,
"variableDebtToken": "0x2ABbAab3EF4e4A899d39e7EC996b5715E76b399a",
"variableDebtTokenImpl": "0x3E59212c34588a63350142EFad594a20C88C2CEd",
"variableDebtTokenName": "Aave Ethereum Lido Variable Debt sUSDe",
"variableDebtTokenSymbol": "variableDebtEthLidosUSDe",
"virtualAccountingActive": true,
"virtualBalance": "100000000000000000000"
}
}
},
"strategies": {
"0x9D39A5DE30e57443BfF2A8307A4256c8797A3497": {
"from": null,
"to": {
"address": "0x8958b1C39269167527821f8c276Ef7504883f2fa",
"baseVariableBorrowRate": "500000000000000000000000",
"maxVariableBorrowRate": "31500000000000000000000000",
"optimalUsageRatio": "10000000000000000000000000",
"variableRateSlope1": "1000000000000000000000000",
"variableRateSlope2": "30000000000000000000000000"
}
}
}
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
## Reserve changes

### Reserves altered

#### sUSDe ([0x9D39A5DE30e57443BfF2A8307A4256c8797A3497](https://etherscan.io/address/0x9D39A5DE30e57443BfF2A8307A4256c8797A3497))

| description | value before | value after |
| --- | --- | --- |
| debtCeiling | 40,000,000 $ [4000000000] | 0 $ [0] |


## Emodes changed

### EMode: ETH correlated(id: 1)



### EMode: sUSDe Stablecoins(id: 2)

| description | value before | value after |
| --- | --- | --- |
| eMode.label | - | sUSDe Stablecoins |
| eMode.ltv | - | 90 % |
| eMode.liquidationThreshold | - | 92 % |
| eMode.liquidationBonus | - | 3 % |
| eMode.borrowableBitmap | - | USDC, USDS |
| eMode.collateralBitmap | - | sUSDe |


## Raw diff

```json
{
"eModes": {
"2": {
"from": null,
"to": {
"borrowableBitmap": 34359738376,
"collateralBitmap": 4294967296,
"eModeCategory": 2,
"label": "sUSDe Stablecoins",
"liquidationBonus": 10300,
"liquidationThreshold": 9200,
"ltv": 9000
}
}
},
"reserves": {
"0x9D39A5DE30e57443BfF2A8307A4256c8797A3497": {
"debtCeiling": {
"from": 4000000000,
"to": 0
}
}
}
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV3EthereumLido, AaveV3EthereumLidoAssets, AaveV3EthereumLidoEModes} from 'aave-address-book/AaveV3EthereumLido.sol';
import {AaveV3PayloadEthereumLido} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadEthereumLido.sol';
import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol';
import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol';
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';
import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol';
import {IEmissionManager} from 'aave-v3-origin/contracts/rewards/interfaces/IEmissionManager.sol';
/**
* @title Onboard and Enable sUSDe liquid E-Mode on Aave v3 Mainnet and Lido Instances
* @author ACI
* - Snapshot: Direct-to-AIP
* - Discussion: https://governance.aave.com/t/arfc-enable-susde-liquid-e-mode-on-aave-v3-mainnet-and-lido-instance/19703
*/
contract AaveV3EthereumLido_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances_20241108 is
AaveV3PayloadEthereumLido
{
using SafeERC20 for IERC20;

address public constant sUSDe = 0x9D39A5DE30e57443BfF2A8307A4256c8797A3497;
uint256 public constant sUSDe_SEED_AMOUNT = 100 * 1e18;
address public constant sUSDe_ADMIN = 0xac140648435d03f784879cd789130F22Ef588Fcd;

function _postExecute() internal override {
IERC20(sUSDe).forceApprove(address(AaveV3EthereumLido.POOL), sUSDe_SEED_AMOUNT);
AaveV3EthereumLido.POOL.supply(
sUSDe,
sUSDe_SEED_AMOUNT,
address(AaveV3EthereumLido.COLLECTOR),
0
);

(address asUSDe, , ) = AaveV3EthereumLido.AAVE_PROTOCOL_DATA_PROVIDER.getReserveTokensAddresses(
sUSDe
);
IEmissionManager(AaveV3EthereumLido.EMISSION_MANAGER).setEmissionAdmin(sUSDe, sUSDe_ADMIN);
IEmissionManager(AaveV3EthereumLido.EMISSION_MANAGER).setEmissionAdmin(asUSDe, sUSDe_ADMIN);
}

function eModeCategoriesUpdates()
public
pure
override
returns (IAaveV3ConfigEngine.EModeCategoryUpdate[] memory)
{
IAaveV3ConfigEngine.EModeCategoryUpdate[]
memory eModeUpdates = new IAaveV3ConfigEngine.EModeCategoryUpdate[](1);

eModeUpdates[0] = IAaveV3ConfigEngine.EModeCategoryUpdate({
eModeCategory: 4,
ltv: 90_00,
liqThreshold: 92_00,
liqBonus: 3_00,
label: 'sUSDe Stablecoins'
});

return eModeUpdates;
}
function assetsEModeUpdates()
public
pure
override
returns (IAaveV3ConfigEngine.AssetEModeUpdate[] memory)
{
IAaveV3ConfigEngine.AssetEModeUpdate[]
memory assetEModeUpdates = new IAaveV3ConfigEngine.AssetEModeUpdate[](3);

assetEModeUpdates[0] = IAaveV3ConfigEngine.AssetEModeUpdate({
asset: sUSDe,
eModeCategory: 4,
borrowable: EngineFlags.DISABLED,
collateral: EngineFlags.ENABLED
});
assetEModeUpdates[1] = IAaveV3ConfigEngine.AssetEModeUpdate({
asset: AaveV3EthereumLidoAssets.USDS_UNDERLYING,
eModeCategory: 4,
borrowable: EngineFlags.ENABLED,
collateral: EngineFlags.DISABLED
});
assetEModeUpdates[2] = IAaveV3ConfigEngine.AssetEModeUpdate({
asset: AaveV3EthereumLidoAssets.USDC_UNDERLYING,
eModeCategory: 4,
borrowable: EngineFlags.ENABLED,
collateral: EngineFlags.DISABLED
});

return assetEModeUpdates;
}
function newListings() public pure override returns (IAaveV3ConfigEngine.Listing[] memory) {
IAaveV3ConfigEngine.Listing[] memory listings = new IAaveV3ConfigEngine.Listing[](1);

listings[0] = IAaveV3ConfigEngine.Listing({
asset: sUSDe,
assetSymbol: 'sUSDe',
priceFeed: 0xb37aE8aBa6C0C1Bf2c509fc06E11aa4AF29B665A,
enabledToBorrow: EngineFlags.DISABLED,
borrowableInIsolation: EngineFlags.DISABLED,
withSiloedBorrowing: EngineFlags.DISABLED,
flashloanable: EngineFlags.ENABLED,
ltv: 5,
liqThreshold: 10,
liqBonus: 7_50,
reserveFactor: 10_00,
supplyCap: 20_000_000,
borrowCap: 1000,
debtCeiling: 0,
liqProtocolFee: 10_00,
rateStrategyParams: IAaveV3ConfigEngine.InterestRateInputData({
optimalUsageRatio: 1_00,
baseVariableBorrowRate: 5,
variableRateSlope1: 10,
variableRateSlope2: 300
})
});

return listings;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol';
import {AaveV3EthereumLido} from 'aave-address-book/AaveV3EthereumLido.sol';
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';
import {IEmissionManager} from 'aave-v3-origin/contracts/rewards/interfaces/IEmissionManager.sol';

import 'forge-std/Test.sol';
import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol';
import {AaveV3EthereumLido_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances_20241108} from './AaveV3EthereumLido_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances_20241108.sol';

/**
* @dev Test for AaveV3EthereumLido_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances_20241108
* command: FOUNDRY_PROFILE=mainnet forge test --match-path=src/20241108_Multi_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances/AaveV3EthereumLido_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances_20241108.t.sol -vv
*/
contract AaveV3EthereumLido_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances_20241108_Test is
ProtocolV3TestBase
{
AaveV3EthereumLido_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances_20241108
internal proposal;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('mainnet'), 21171005);
proposal = new AaveV3EthereumLido_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances_20241108();
}

/**
* @dev executes the generic test suite including e2e and config snapshots
*/
function test_defaultProposalExecution() public {
defaultTest(
'AaveV3EthereumLido_OnboardAndEnableSUSDeLiquidEModeOnAaveV3MainnetAndLidoInstances_20241108',
AaveV3EthereumLido.POOL,
address(proposal)
);
}

function test_collectorHassUSDeFunds() public {
GovV3Helpers.executePayload(vm, address(proposal));
(address aTokenAddress, , ) = AaveV3EthereumLido
.AAVE_PROTOCOL_DATA_PROVIDER
.getReserveTokensAddresses(proposal.sUSDe());
assertGe(
IERC20(aTokenAddress).balanceOf(address(AaveV3EthereumLido.COLLECTOR)),
100 * 10 ** 18
);
}

function test_sUSDeAdmin() public {
GovV3Helpers.executePayload(vm, address(proposal));
(address asUSDe, , ) = AaveV3EthereumLido.AAVE_PROTOCOL_DATA_PROVIDER.getReserveTokensAddresses(
proposal.sUSDe()
);
assertEq(
IEmissionManager(AaveV3EthereumLido.EMISSION_MANAGER).getEmissionAdmin(proposal.sUSDe()),
proposal.sUSDe_ADMIN()
);
assertEq(
IEmissionManager(AaveV3EthereumLido.EMISSION_MANAGER).getEmissionAdmin(asUSDe),
proposal.sUSDe_ADMIN()
);
}
}
Loading

0 comments on commit 5ad1d7f

Please sign in to comment.