Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onboard USDe - Review #345

Merged
merged 3 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .assets/a2ff7054b21a6d938826bbea32b5e589c6a0c8f7.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions .assets/c73865a243e2110291617da971e6614d404cd2c5.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
## Reserve changes

### Reserves added

#### USDe ([0x4c9EDD5852cd905f086C759E8383e09bff1E68B3](https://etherscan.io/address/0x4c9EDD5852cd905f086C759E8383e09bff1E68B3))

| description | value |
| --- | --- |
| decimals | 18 |
| isActive | true |
| isFrozen | false |
| supplyCap | 80,000,000 USDe |
| borrowCap | 72,000,000 USDe |
| debtCeiling | 40,000,000 $ |
| isSiloed | false |
| isFlashloanable | true |
| eModeCategory | 0 |
| oracle | [0x55B6C4D3E8A27b8A1F5a263321b602e0fdEEcC17](https://etherscan.io/address/0x55B6C4D3E8A27b8A1F5a263321b602e0fdEEcC17) |
| oracleDecimals | 8 |
| oracleDescription | Capped USDe / USD |
| oracleLatestAnswer | 1.00079999 |
| usageAsCollateralEnabled | true |
| ltv | 72 % |
| liquidationThreshold | 75 % |
| liquidationBonus | 8.5 % |
| liquidationProtocolFee | 10 % |
| reserveFactor | 25 % |
| aToken | [0x4F5923Fc5FD4a93352581b38B7cD26943012DECF](https://etherscan.io/address/0x4F5923Fc5FD4a93352581b38B7cD26943012DECF) |
| aTokenImpl | [0x7EfFD7b47Bfd17e52fB7559d3f924201b9DbfF3d](https://etherscan.io/address/0x7EfFD7b47Bfd17e52fB7559d3f924201b9DbfF3d) |
| variableDebtToken | [0x015396E1F286289aE23a762088E863b3ec465145](https://etherscan.io/address/0x015396E1F286289aE23a762088E863b3ec465145) |
| variableDebtTokenImpl | [0xaC725CB59D16C81061BDeA61041a8A5e73DA9EC6](https://etherscan.io/address/0xaC725CB59D16C81061BDeA61041a8A5e73DA9EC6) |
| stableDebtToken | [0x43Cc8AD0c223b38D9c04802bB184A2D97e497D38](https://etherscan.io/address/0x43Cc8AD0c223b38D9c04802bB184A2D97e497D38) |
| stableDebtTokenImpl | [0x15C5620dfFaC7c7366EED66C20Ad222DDbB1eD57](https://etherscan.io/address/0x15C5620dfFaC7c7366EED66C20Ad222DDbB1eD57) |
| borrowingEnabled | true |
| stableBorrowRateEnabled | false |
| isBorrowableInIsolation | true |
| interestRateStrategy | [0x4011fcd421b9E90f131B164EC1d162DBE269621C](https://etherscan.io/address/0x4011fcd421b9E90f131B164EC1d162DBE269621C) |
| liquidityIndex | 1 |
| variableBorrowIndex | 1 |
| aTokenName | Aave Ethereum USDe |
| aTokenSymbol | aEthUSDe |
| currentLiquidityRate | 0 % |
| currentVariableBorrowRate | 0 % |
| isPaused | false |
| stableDebtTokenName | Aave Ethereum Stable Debt USDe |
| stableDebtTokenSymbol | stableDebtEthUSDe |
| variableDebtTokenName | Aave Ethereum Variable Debt USDe |
| variableDebtTokenSymbol | variableDebtEthUSDe |
| optimalUsageRatio | 80 % |
| maxExcessStableToTotalDebtRatio | 100 % |
| maxExcessUsageRatio | 20 % |
| optimalStableToTotalDebtRatio | 0 % |
| baseVariableBorrowRate | 0 % |
| variableRateSlope1 | 9 % |
| variableRateSlope2 | 75 % |
| baseStableBorrowRate | 9 % |
| stableRateSlope1 | 9 % |
| stableRateSlope2 | 75 % |
| interestRate | ![ir](/.assets/a2ff7054b21a6d938826bbea32b5e589c6a0c8f7.svg) |


## Raw diff

```json
{
"reserves": {
"0x4c9EDD5852cd905f086C759E8383e09bff1E68B3": {
"from": null,
"to": {
"aToken": "0x4F5923Fc5FD4a93352581b38B7cD26943012DECF",
"aTokenImpl": "0x7EfFD7b47Bfd17e52fB7559d3f924201b9DbfF3d",
"aTokenName": "Aave Ethereum USDe",
"aTokenSymbol": "aEthUSDe",
"borrowCap": 72000000,
"borrowingEnabled": true,
"currentLiquidityRate": 0,
"currentVariableBorrowRate": 0,
"debtCeiling": 4000000000,
"decimals": 18,
"eModeCategory": 0,
"interestRateStrategy": "0x4011fcd421b9E90f131B164EC1d162DBE269621C",
"isActive": true,
"isBorrowableInIsolation": true,
"isFlashloanable": true,
"isFrozen": false,
"isPaused": false,
"isSiloed": false,
"liquidationBonus": 10850,
"liquidationProtocolFee": 1000,
"liquidationThreshold": 7500,
"liquidityIndex": "1000000000000000000000000000",
"ltv": 7200,
"oracle": "0x55B6C4D3E8A27b8A1F5a263321b602e0fdEEcC17",
"oracleDecimals": 8,
"oracleDescription": "Capped USDe / USD",
"oracleLatestAnswer": 100079999,
"reserveFactor": 2500,
"stableBorrowRateEnabled": false,
"stableDebtToken": "0x43Cc8AD0c223b38D9c04802bB184A2D97e497D38",
"stableDebtTokenImpl": "0x15C5620dfFaC7c7366EED66C20Ad222DDbB1eD57",
"stableDebtTokenName": "Aave Ethereum Stable Debt USDe",
"stableDebtTokenSymbol": "stableDebtEthUSDe",
"supplyCap": 80000000,
"symbol": "USDe",
"underlying": "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3",
"usageAsCollateralEnabled": true,
"variableBorrowIndex": "1000000000000000000000000000",
"variableDebtToken": "0x015396E1F286289aE23a762088E863b3ec465145",
"variableDebtTokenImpl": "0xaC725CB59D16C81061BDeA61041a8A5e73DA9EC6",
"variableDebtTokenName": "Aave Ethereum Variable Debt USDe",
"variableDebtTokenSymbol": "variableDebtEthUSDe"
}
}
},
"strategies": {
"0x4c9EDD5852cd905f086C759E8383e09bff1E68B3": {
"from": null,
"to": {
"address": "0x4011fcd421b9E90f131B164EC1d162DBE269621C",
"baseStableBorrowRate": "90000000000000000000000000",
"baseVariableBorrowRate": 0,
"maxExcessStableToTotalDebtRatio": "1000000000000000000000000000",
"maxExcessUsageRatio": "200000000000000000000000000",
"optimalStableToTotalDebtRatio": 0,
"optimalUsageRatio": "800000000000000000000000000",
"stableRateSlope1": "90000000000000000000000000",
"stableRateSlope2": "750000000000000000000000000",
"variableRateSlope1": "90000000000000000000000000",
"variableRateSlope2": "750000000000000000000000000"
}
}
}
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV3Ethereum, AaveV3EthereumEModes} from 'aave-address-book/AaveV3Ethereum.sol';
import {AaveV3PayloadEthereum} from 'aave-helpers/v3-config-engine/AaveV3PayloadEthereum.sol';
import {EngineFlags} from 'aave-helpers/v3-config-engine/EngineFlags.sol';
import {IAaveV3ConfigEngine} from 'aave-helpers/v3-config-engine/IAaveV3ConfigEngine.sol';
import {IV3RateStrategyFactory} from 'aave-helpers/v3-config-engine/IV3RateStrategyFactory.sol';
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';
import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol';
/**
* @title Onboard USDe Aave V3 Ethereum
* @author ACI
* - Snapshot: https://snapshot.org/#/aave.eth/proposal/0xc1b6d0d390a2dabf81206f592f740c69163dd028dcb0f50182d0ad3a50e744b0
* - Discussion: https://governance.aave.com/t/arfc-onboard-usde-to-aave-v3-on-ethereum/17690
*/
contract AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528 is AaveV3PayloadEthereum {
using SafeERC20 for IERC20;

address public constant USDe = 0x4c9EDD5852cd905f086C759E8383e09bff1E68B3;
uint256 public constant USDe_SEED_AMOUNT = 1e18;

function _postExecute() internal override {
IERC20(USDe).forceApprove(address(AaveV3Ethereum.POOL), USDe_SEED_AMOUNT);
AaveV3Ethereum.POOL.supply(USDe, USDe_SEED_AMOUNT, address(AaveV3Ethereum.COLLECTOR), 0);
}

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

listings[0] = IAaveV3ConfigEngine.Listing({
asset: USDe,
assetSymbol: 'USDe',
priceFeed: 0x55B6C4D3E8A27b8A1F5a263321b602e0fdEEcC17,
eModeCategory: AaveV3EthereumEModes.NONE,
enabledToBorrow: EngineFlags.ENABLED,
stableRateModeEnabled: EngineFlags.DISABLED,
borrowableInIsolation: EngineFlags.ENABLED,
withSiloedBorrowing: EngineFlags.DISABLED,
flashloanable: EngineFlags.ENABLED,
ltv: 72_00,
liqThreshold: 75_00,
liqBonus: 8_50,
reserveFactor: 25_00,
supplyCap: 80_000_000,
borrowCap: 72_000_000,
debtCeiling: 40_000_000,
liqProtocolFee: 10_00,
rateStrategyParams: IV3RateStrategyFactory.RateStrategyParams({
optimalUsageRatio: _bpsToRay(80_00),
baseVariableBorrowRate: _bpsToRay(0),
variableRateSlope1: _bpsToRay(9_00),
variableRateSlope2: _bpsToRay(75_00),
stableRateSlope1: _bpsToRay(9_00),
stableRateSlope2: _bpsToRay(75_00),
baseStableRateOffset: _bpsToRay(0),
stableRateExcessOffset: _bpsToRay(0),
optimalStableToTotalDebtRatio: _bpsToRay(0)
})
});

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

import {GovV3Helpers} from 'aave-helpers/GovV3Helpers.sol';
import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol';
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';

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

/**
* @dev Test for AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528
* command: FOUNDRY_PROFILE=mainnet forge test --match-path=src/20240528_AaveV3Ethereum_OnboardUSDeAaveV3Ethereum/AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528.t.sol -vv
*/
contract AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528_Test is ProtocolV3TestBase {
AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528 internal proposal;

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

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

function test_collectorHasUSDeFunds() public {
GovV3Helpers.executePayload(vm, address(proposal));
(address aTokenAddress, , ) = AaveV3Ethereum
.AAVE_PROTOCOL_DATA_PROVIDER
.getReserveTokensAddresses(proposal.USDe());
assertGe(IERC20(aTokenAddress).balanceOf(address(AaveV3Ethereum.COLLECTOR)), 10 ** 18);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: "Onboard USDe Aave V3 Ethereum"
author: "ACI"
discussions: "https://governance.aave.com/t/arfc-onboard-usde-to-aave-v3-on-ethereum/17690"
snapshot: "https://snapshot.org/#/aave.eth/proposal/0xc1b6d0d390a2dabf81206f592f740c69163dd028dcb0f50182d0ad3a50e744b0"
---

## Simple Summary

This proposal seek approval for the addition of USDe to Aave V3 on Ethereum

## Motivation

Ethena’s synthetic dollar, USDe, provides a stable crypto-native solution for a cash and carry structured product. The staked version of USDe, sUSDe, earns yield from the protocol and has high potential for strong borrow demand.

## Specification

The table below illustrates the configured risk parameters for **USDe**

| Parameter | Value |
| ---------------------------------- | -----------------------------------------: |
| Isolation Mode | true |
| Borrowable | ENABLED |
| Collateral Enabled | true |
| Supply Cap (USDe) | 80,000,000 |
| Borrow Cap (USDe) | 72,000,000 |
| Debt Ceiling | USD 40,000,000 |
| LTV | 72 % |
| LT | 75 % |
| Liquidation Bonus | 8.5 % |
| Liquidation Protocol Fee | 10 % |
| Reserve Factor | 25 % |
| Base Variable Borrow Rate | 0 % |
| Variable Slope 1 | 9 % |
| Variable Slope 2 | 75 % |
| Uoptimal | 80 % |
| Stable Borrowing | DISABLED |
| Stable Slope1 | 9 % |
| Stable Slope2 | 75 % |
| Base Stable Rate Offset | 0 % |
| Stable Rate Excess Offset | 0 % |
| Optimal Stable To Total Debt Ratio | 0 % |
| Flashloanable | ENABLED |
| Siloed Borrowing | DISABLED |
| Borrowable in Isolation | ENABLED |
| Oracle | 0x55B6C4D3E8A27b8A1F5a263321b602e0fdEEcC17 |

## References

- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240528_AaveV3Ethereum_OnboardUSDeAaveV3Ethereum/AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528.sol)
- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240528_AaveV3Ethereum_OnboardUSDeAaveV3Ethereum/AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528.t.sol)
- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0xc1b6d0d390a2dabf81206f592f740c69163dd028dcb0f50182d0ad3a50e744b0)
- [Discussion](https://governance.aave.com/t/arfc-onboard-usde-to-aave-v3-on-ethereum/17690)

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/GovV3Helpers.sol';
import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol';
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';
import {EthereumScript} from 'aave-helpers/ScriptUtils.sol';
import {AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528} from './AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528.sol';

/**
* @dev Deploy Ethereum
* deploy-command: make deploy-ledger contract=src/20240528_AaveV3Ethereum_OnboardUSDeAaveV3Ethereum/OnboardUSDeAaveV3Ethereum_20240528.s.sol:DeployEthereum chain=mainnet
* verify-command: FOUNDRY_PROFILE=mainnet npx catapulta-verify -b broadcast/OnboardUSDeAaveV3Ethereum_20240528.s.sol/1/run-latest.json
*/
contract DeployEthereum is EthereumScript {
function run() external broadcast {
// deploy payloads
address payload0 = GovV3Helpers.deployDeterministic(
type(AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528).creationCode
);

// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(payload0);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Create Proposal
* command: make deploy-ledger contract=src/20240528_AaveV3Ethereum_OnboardUSDeAaveV3Ethereum/OnboardUSDeAaveV3Ethereum_20240528.s.sol:CreateProposal chain=mainnet
*/
contract CreateProposal is EthereumScript {
function run() external {
// create payloads
PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](1);

// compose actions for validation
IPayloadsControllerCore.ExecutionAction[]
memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1);
actionsEthereum[0] = GovV3Helpers.buildAction(
type(AaveV3Ethereum_OnboardUSDeAaveV3Ethereum_20240528).creationCode
);
payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum);

// create proposal
vm.startBroadcast();
GovV3Helpers.createProposal(
vm,
payloads,
GovernanceV3Ethereum.VOTING_PORTAL_ETH_POL,
GovV3Helpers.ipfsHashFile(
vm,
'src/20240528_AaveV3Ethereum_OnboardUSDeAaveV3Ethereum/OnboardUSDeAaveV3Ethereum.md'
)
);
}
}
Loading
Loading