Skip to content

Commit

Permalink
TUSD offboarding plan - Review (bgd-labs#237)
Browse files Browse the repository at this point in the history
* init

* updated test

* fix

* fix diff report
  • Loading branch information
Marc Zeller authored Aug 1, 2023
1 parent c4d581f commit 67a42d0
Show file tree
Hide file tree
Showing 5 changed files with 309 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
## Reserve changes

### Reserves altered

#### TUSD ([0x0000000000085d4780B73119b644AE5ecd22b376](https://etherscan.io/address/0x0000000000085d4780B73119b644AE5ecd22b376))

| description | value before | value after |
| --- | --- | --- |
| ltv | 75 % | 0 % |
| liquidationThreshold | 77.5 % | 75 % |
| liquidationBonus | 5 % | 10 % |
| reserveFactor | 25 % | 95 % |
| borrowingEnabled | true | false |
| stableBorrowRateEnabled | true | false |
| interestRateStrategy | [0x6bcE15B789e537f3abA3C60CB183F0E8737f05eC](https://etherscan.io/address/0x6bcE15B789e537f3abA3C60CB183F0E8737f05eC) | [0x67a81df2b7FAf4a324D94De9Cc778704F4500478](https://etherscan.io/address/0x67a81df2b7FAf4a324D94De9Cc778704F4500478) |
| optimalUsageRatio | 80 % | 20 % |
| maxExcessUsageRatio | 20 % | 80 % |
| baseVariableBorrowRate | 0 % | 3 % |
| variableRateSlope1 | 4 % | 7 % |
| variableRateSlope2 | 100 % | 200 % |
| stableRateSlope1 | 2 % | 7 % |
| stableRateSlope2 | 100 % | 2000 % |
| interestRate | ![before](/.assets/2e987a4911a41c316461bd57acf38be5b6ae837b.svg) | ![after](/.assets/66940b7cfc53826ed2d6a31e1a82473e8d7325a1.svg) |

## Raw diff

```json
{
"reserves": {
"0x0000000000085d4780B73119b644AE5ecd22b376": {
"borrowingEnabled": {
"from": true,
"to": false
},
"interestRateStrategy": {
"from": "0x6bcE15B789e537f3abA3C60CB183F0E8737f05eC",
"to": "0x67a81df2b7FAf4a324D94De9Cc778704F4500478"
},
"liquidationBonus": {
"from": 10500,
"to": 11000
},
"liquidationThreshold": {
"from": 7750,
"to": 7500
},
"ltv": {
"from": 7500,
"to": 0
},
"reserveFactor": {
"from": 2500,
"to": 9500
},
"stableBorrowRateEnabled": {
"from": true,
"to": false
}
}
},
"strategies": {
"0x67a81df2b7FAf4a324D94De9Cc778704F4500478": {
"from": null,
"to": {
"baseVariableBorrowRate": "30000000000000000000000000",
"maxExcessUsageRatio": "800000000000000000000000000",
"optimalUsageRatio": "200000000000000000000000000",
"stableRateSlope1": "70000000000000000000000000",
"stableRateSlope2": "20000000000000000000000000000",
"variableRateSlope1": "70000000000000000000000000",
"variableRateSlope2": "2000000000000000000000000000"
}
}
}
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovHelpers} from 'aave-helpers/GovHelpers.sol';
import {EthereumScript} from 'aave-helpers/ScriptUtils.sol';
import {AaveV2_Eth_TUSDOffboardingPlan_20233107} from './AaveV2_Eth_TUSDOffboardingPlan_20233107.sol';

/**
* @dev Deploy AaveV2_Eth_TUSDOffboardingPlan_20233107
* command: make deploy-ledger contract=src/AaveV2_Eth_TUSDOffboardingPlan_20233107/AaveV2_Eth_TUSDOffboardingPlan_20233107.s.sol:DeployEthereum chain=mainnet
*/
contract DeployEthereum is EthereumScript {
function run() external broadcast {
new AaveV2_Eth_TUSDOffboardingPlan_20233107();
}
}

/**
* @dev Create Proposal
* command: make deploy-ledger contract=src/AaveV2_Eth_TUSDOffboardingPlan_20233107/AaveV2_Eth_TUSDOffboardingPlan_20233107.s.sol:CreateProposal chain=mainnet
*/
contract CreateProposal is EthereumScript {
function run() external broadcast {
GovHelpers.Payload[] memory payloads = new GovHelpers.Payload[](1);
payloads[0] = GovHelpers.buildMainnet(address(0));
GovHelpers.createProposal(
payloads,
GovHelpers.ipfsHashFile(
vm,
'src/AaveV2_Eth_TUSDOffboardingPlan_20233107/TUSDOffboardingPlan.md'
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol';
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';

/**
* @title TUSD offboarding plan
* @author Marc Zeller (@marczeller - Aave Chan Initiative), Gauntlet
* - Snapshot: https://snapshot.org/#/aave.eth/proposal/0xfd0cdbf58992759f47e6f5a6c07cbeb2b1a02af1c9ebf7d3099b80c33f53c138
* - Discussion: https://governance.aave.com/t/arfc-tusd-offboarding-plan/14008
*/
contract AaveV2_Eth_TUSDOffboardingPlan_20233107 {
address public constant INTEREST_RATE_STRATEGY = 0x67a81df2b7FAf4a324D94De9Cc778704F4500478;
uint256 public constant TUSD_LTV = 0; /// 80 -> 0
uint256 public constant TUSD_LIQUIDATION_THRESHOLD = 75_00; // 77.5 -> 75
uint256 public constant TUSD_LIQUIDATION_BONUS = 11000; // 5 -> 10
uint256 public constant RESERVE_FACTOR = 95_00; // 10 -> 95

function execute() external {
// set LTV to Zero, decrease liquidation threshold and increase liquiditation bonus

AaveV2Ethereum.POOL_CONFIGURATOR.configureReserveAsCollateral(
AaveV2EthereumAssets.TUSD_UNDERLYING,
TUSD_LTV,
TUSD_LIQUIDATION_THRESHOLD,
TUSD_LIQUIDATION_BONUS
);

// set reserve factor to 95%

AaveV2Ethereum.POOL_CONFIGURATOR.setReserveFactor(
AaveV2EthereumAssets.TUSD_UNDERLYING,
RESERVE_FACTOR
);

// disable borrowing on TUSD

AaveV2Ethereum.POOL_CONFIGURATOR.disableBorrowingOnReserve(
AaveV2EthereumAssets.TUSD_UNDERLYING
);

// disable stable rate borrowing on TUSD

AaveV2Ethereum.POOL_CONFIGURATOR.disableReserveStableRate(AaveV2EthereumAssets.TUSD_UNDERLYING);

// unlike BUSD AIP, we withdraw TUSD from pool first then change the rate strategy following BGD labs recommendations

uint256 aTUSDBalance = IERC20(AaveV2EthereumAssets.TUSD_A_TOKEN).balanceOf(
address(AaveV2Ethereum.COLLECTOR)
);
uint256 availableTUSD = IERC20(AaveV2EthereumAssets.TUSD_UNDERLYING).balanceOf(
AaveV2EthereumAssets.TUSD_A_TOKEN
);
AaveV2Ethereum.COLLECTOR.transfer(
AaveV2EthereumAssets.TUSD_A_TOKEN,
address(this),
aTUSDBalance > availableTUSD ? availableTUSD : aTUSDBalance
);
AaveV2Ethereum.POOL.withdraw(
AaveV2EthereumAssets.TUSD_UNDERLYING,
type(uint256).max,
address(AaveV2Ethereum.COLLECTOR)
);

AaveV2Ethereum.POOL_CONFIGURATOR.setReserveInterestRateStrategyAddress(
AaveV2EthereumAssets.TUSD_UNDERLYING,
INTEREST_RATE_STRATEGY
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import 'forge-std/Test.sol';
import {GovHelpers} from 'aave-helpers/GovHelpers.sol';
import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol';
import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol';
import {ProtocolV2TestBase, ReserveConfig} from 'aave-helpers/ProtocolV2TestBase.sol';
import {AaveV2_Eth_TUSDOffboardingPlan_20233107} from './AaveV2_Eth_TUSDOffboardingPlan_20233107.sol';
import {IERC20} from 'lib/solidity-utils/src/contracts/oz-common/interfaces/IERC20.sol';

/**
* @dev Test for AaveV2_Eth_TUSDOffboardingPlan_20233107
* command: make test-contract filter=AaveV2_Eth_TUSDOffboardingPlan_20233107
*/
contract AaveV2_Eth_TUSDOffboardingPlan_20233107_Test is ProtocolV2TestBase {
string public constant TUSD_SYMBOL = 'TUSD';

function setUp() public {
vm.createSelectFork(vm.rpcUrl('mainnet'), 17812148);
}

function testProposalExecution() public {
AaveV2_Eth_TUSDOffboardingPlan_20233107 proposal = new AaveV2_Eth_TUSDOffboardingPlan_20233107();

ReserveConfig[] memory allConfigsBefore = createConfigurationSnapshot(
'preAaveV2_Eth_TUSDOffboardingPlan_20233107',
AaveV2Ethereum.POOL
);

ReserveConfig memory configTUSDBefore = _findReserveConfigBySymbol(
allConfigsBefore,
TUSD_SYMBOL
);

uint256 aTUSDBalanceBefore = IERC20(AaveV2EthereumAssets.TUSD_A_TOKEN).balanceOf(
address(AaveV2Ethereum.COLLECTOR)
);
uint256 TUSDBalanceBefore = IERC20(AaveV2EthereumAssets.TUSD_UNDERLYING).balanceOf(
address(AaveV2Ethereum.COLLECTOR)
);

GovHelpers.executePayload(vm, address(proposal), AaveGovernanceV2.SHORT_EXECUTOR);

// check balances are correct
uint256 aTUSDBalanceAfter = IERC20(AaveV2EthereumAssets.TUSD_A_TOKEN).balanceOf(
address(AaveV2Ethereum.COLLECTOR)
);
uint256 TUSDBalanceAfter = IERC20(AaveV2EthereumAssets.TUSD_UNDERLYING).balanceOf(
address(AaveV2Ethereum.COLLECTOR)
);
assertApproxEqAbs(aTUSDBalanceAfter, 0, 1500 ether, 'aTUSD_LEFTOVER');
assertEq(TUSDBalanceAfter, aTUSDBalanceBefore + TUSDBalanceBefore);

ReserveConfig[] memory allConfigsAfter = createConfigurationSnapshot(
'postAaveV2_Eth_TUSDOffboardingPlan_20233107',
AaveV2Ethereum.POOL
);

// check it's not bricked
ReserveConfig memory configTUSDAfter = _findReserveConfigBySymbol(allConfigsAfter, TUSD_SYMBOL);
_withdraw(
configTUSDAfter,
AaveV2Ethereum.POOL,
0x9FCc67D7DB763787BB1c7f3bC7f34d3C548c19Fe,
1 ether
); // aTUSD whale

// check there are no unexpected changes
_noReservesConfigsChangesApartFrom(
allConfigsBefore,
allConfigsAfter,
configTUSDBefore.underlying
);

e2eTest(AaveV2Ethereum.POOL);

diffReports(
'preAaveV2_Eth_TUSDOffboardingPlan_20233107',
'postAaveV2_Eth_TUSDOffboardingPlan_20233107'
);
}
}
45 changes: 45 additions & 0 deletions src/AaveV2_Eth_TUSDOffboardingPlan_20233107/TUSDOffboardingPlan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
title: TUSD offboarding plan
author: Marc Zeller (@marczeller - Aave Chan Initiative), Gauntlet
discussions: https://governance.aave.com/t/arfc-tusd-offboarding-plan/14008
---

## Simple Summary

This proposal aims to initiate the offboarding process for TUSD from the Aave V2 Ethereum pool. The process will follow a similar process as the [BUSD offboarding plan part I](https://governance.aave.com/t/arfc-busd-offboarding-plan/12170).

## Motivation

TUSD has been a historic asset of the Aave ecosystem, but due to recent events, the ACI suggests consideration of its offboarding. The offboarding plan leverages the previous success of the BUSD offboarding plan and will incentive current users to slowly migrate their positions to other stablecoins on Aave.


Previous proposals have [frozen TUSD](https://app.aave.com/governance/proposal/253/) and [lowered TUSD LT to 77.5%. ](https://app.aave.com/governance/proposal/256/) These proposals have reduced TUSD borrow and supply over the past 30 days, from 20M supplied and 18M borrowed, to 13.1M supplied and 6.8M borrowed today.

## Specification

The following table outlines the proposed changes to the TUSD risk parameters:

| Parameter | Current Value | Proposed Value |
|--------------------------|---------------|----------------|
| LTV | 75% | 0% |
| Liquidation Threshold | 77.5% | 75% |
| Liquidation Bonus | 5% | 10% |
| Reserve Factor | 25% | 95% |
| Borrowing Enabled | Yes | No |
| Stable Borrowing Enabled | Yes | No |
| Base Rate | 0% | 3% |
| Slope1 | 4% | 7% |
| Slope2 | 100% | 200% |
| UOptimal | 80% | 20% |


## References

- Implementation: [Ethereum](https://github.com/bgd-labs/aave-proposals/blob/main/src/AaveV2_Eth_TUSDOffboardingPlan_20233107/AaveV2_Eth_TUSDOffboardingPlan_20233107.sol)
- Tests: [Ethereum](https://github.com/bgd-labs/aave-proposals/blob/main/src/AaveV2_Eth_TUSDOffboardingPlan_20233107/AaveV2_Eth_TUSDOffboardingPlan_20233107.t.sol)
- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0xfd0cdbf58992759f47e6f5a6c07cbeb2b1a02af1c9ebf7d3099b80c33f53c138)
- [Discussion](https://governance.aave.com/t/arfc-tusd-offboarding-plan/14008)

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

0 comments on commit 67a42d0

Please sign in to comment.