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

Feat/plausibility #152

Merged
merged 4 commits into from
Oct 16, 2023
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/12accf0fd189bd0ec8f5f33b46f04aa39ddfe4c0.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/36935a8fd1d50a51974d60fcb6323e9bc9a95c16.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/66aa72f6fe3716b9b6a43abb25a455671672849e.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/729f8480b862f1b9d32ce1e3eaa4e55f4562d75b.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/a74b1b2d3fed4f05761618942237126d814b6f7e.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/ebd346a83b729edecf1938b8cdd0528700c8b9fd.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions diffs/default_before_default_after.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Raw diff

```json
{}
```
1,188 changes: 1,188 additions & 0 deletions reports/default_after.json

Large diffs are not rendered by default.

1,188 changes: 1,188 additions & 0 deletions reports/default_before.json

Large diffs are not rendered by default.

83 changes: 69 additions & 14 deletions src/ProtocolV3TestBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,15 @@ pragma solidity >=0.7.5 <0.9.0;
import 'forge-std/Test.sol';
import {IAaveOracle, IPool, IPoolAddressesProvider, IPoolDataProvider, IDefaultInterestRateStrategy, DataTypes, IPoolConfigurator} from 'aave-address-book/AaveV3.sol';
import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';
import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol';
import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol';
import {IInitializableAdminUpgradeabilityProxy} from './interfaces/IInitializableAdminUpgradeabilityProxy.sol';
import {ExtendedAggregatorV2V3Interface} from './interfaces/ExtendedAggregatorV2V3Interface.sol';
import {ProxyHelpers} from './ProxyHelpers.sol';
import {CommonTestBase, ReserveTokens} from './CommonTestBase.sol';
import {ReserveConfiguration} from 'aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol';
import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol';

interface IERC20Detailed is IERC20 {
function name() external view returns (string memory);

function symbol() external view returns (string memory);

function decimals() external view returns (uint8);
}
import {GovV3Helpers} from './GovV3Helpers.sol';

struct ReserveConfig {
string symbol;
Expand Down Expand Up @@ -72,6 +66,60 @@ contract ProtocolV3TestBase is CommonTestBase {
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
using SafeERC20 for IERC20;

function defaultTest(
string memory reportName,
IPool pool,
address payload
) public returns (ReserveConfig[] memory, ReserveConfig[] memory) {
string memory beforeString = string(abi.encodePacked(reportName, '_before'));
ReserveConfig[] memory configBefore = createConfigurationSnapshot(beforeString, pool);

GovV3Helpers.executePayload(vm, payload);

string memory afterString = string(abi.encodePacked(reportName, '_after'));
ReserveConfig[] memory configAfter = createConfigurationSnapshot(afterString, pool);

diffReports(beforeString, afterString);

configChangePlausibilityTest(configBefore, configAfter);

e2eTest(pool);
return (configBefore, configAfter);
}

function configChangePlausibilityTest(
ReserveConfig[] memory configBefore,
ReserveConfig[] memory configAfter
) public {
uint256 configsBeforeLength = configBefore.length;
for (uint256 i = 0; i < configAfter.length; i++) {
// assets are ususally not permanently unlisted, so the expectation is there will only be addition
// if config existed before
if (i < configsBeforeLength) {
// borrow increase should only happen on assets with borrowing enabled
if (configBefore[i].borrowCap < configAfter[i].borrowCap) {
require(configAfter[i].borrowingEnabled, 'PL_BORROW_CAP_BORROW_DISABLED');
}
} else {
// at least newly listed assets should never have a supply cap exceeding total supply
uint256 totalSupply = IERC20(configAfter[i].underlying).totalSupply();
require(
configAfter[i].supplyCap / 1e2 <=
totalSupply / IERC20Metadata(configAfter[i].underlying).decimals(),
'PL_SUPPLY_CAP_GT_TOTAL_SUPPLY'
);
}
// borrow cap should never exceed supply cap
if (
configAfter[i].borrowCap != 0 &&
configAfter[i].underlying != AaveV3EthereumAssets.GHO_UNDERLYING // GHO is the exlcusion from the rule
) {
console.log(configAfter[i].underlying);
require(configAfter[i].borrowCap <= configAfter[i].supplyCap, 'PL_SUPPLY_LT_BORROW');
}
}
}

/**
* @dev Generates a markdown compatible snapshot of the whole pool configuration into `/reports`.
* @param reportName filename suffix for the generated reports.
Expand Down Expand Up @@ -182,6 +230,13 @@ contract ProtocolV3TestBase is CommonTestBase {
vm.revertTo(snapshot);
// test variable borrowing
if (testAssetConfig.borrowingEnabled) {
if (
(testAssetConfig.borrowCap * 10 ** testAssetConfig.decimals) <
IERC20(testAssetConfig.variableDebtToken).totalSupply() + testAssetAmount
) {
console.log('Skip Borrowing: %s, borrow cap fully utilized', testAssetConfig.symbol);
return;
}
_e2eTestBorrowRepay(pool, collateralSupplier, testAssetConfig, testAssetAmount, false);
vm.revertTo(snapshot);
// test stable borrowing
Expand Down Expand Up @@ -466,8 +521,8 @@ contract ProtocolV3TestBase is CommonTestBase {
'aTokenImpl',
ProxyHelpers.getInitializableAdminUpgradeabilityProxyImplementation(vm, config.aToken)
);
vm.serializeString(key, 'aTokenSymbol', IERC20Detailed(config.aToken).symbol());
vm.serializeString(key, 'aTokenName', IERC20Detailed(config.aToken).name());
vm.serializeString(key, 'aTokenSymbol', IERC20Metadata(config.aToken).symbol());
vm.serializeString(key, 'aTokenName', IERC20Metadata(config.aToken).name());
vm.serializeAddress(
key,
'stableDebtTokenImpl',
Expand All @@ -479,9 +534,9 @@ contract ProtocolV3TestBase is CommonTestBase {
vm.serializeString(
key,
'stableDebtTokenSymbol',
IERC20Detailed(config.stableDebtToken).symbol()
IERC20Metadata(config.stableDebtToken).symbol()
);
vm.serializeString(key, 'stableDebtTokenName', IERC20Detailed(config.stableDebtToken).name());
vm.serializeString(key, 'stableDebtTokenName', IERC20Metadata(config.stableDebtToken).name());
vm.serializeAddress(
key,
'variableDebtTokenImpl',
Expand All @@ -493,12 +548,12 @@ contract ProtocolV3TestBase is CommonTestBase {
vm.serializeString(
key,
'variableDebtTokenSymbol',
IERC20Detailed(config.variableDebtToken).symbol()
IERC20Metadata(config.variableDebtToken).symbol()
);
vm.serializeString(
key,
'variableDebtTokenName',
IERC20Detailed(config.variableDebtToken).name()
IERC20Metadata(config.variableDebtToken).name()
);
vm.serializeAddress(key, 'oracle', address(assetOracle));
if (address(assetOracle) != address(0)) {
Expand Down
18 changes: 12 additions & 6 deletions tests/GovV3Test.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ pragma solidity ^0.8.0;
import 'forge-std/Test.sol';
import {IVotingMachineWithProofs, GovV3Helpers, PayloadsControllerUtils, IPayloadsControllerCore, GovV3StorageHelpers, IGovernanceCore} from '../src/GovV3Helpers.sol';
import {GovHelpers} from '../src/GovHelpers.sol';
import {ProtocolV3TestBase} from '../src/ProtocolV3TestBase.sol';
import {AaveMisc} from 'aave-address-book/AaveMisc.sol';
import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol';
import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol';
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';

Expand All @@ -14,18 +16,18 @@ interface Mock {
function guardian() external view returns (address);
}

contract GovernanceV3Test is Test {
contract GovernanceV3Test is ProtocolV3TestBase {
event TestEvent();

PayloadWithEmit payload;

address public constant LONG_PROPOSAL = 0x6195a956dC026A949dE552F04a5803d3aa1fC408;
uint256 public constant LONG_PROPOSAL_ID = 345;
address public constant SHORT_PROPOSAL = 0xa59262276dB8F997948fdc4a10cBc1448A375636;

function setUp() public {
vm.createSelectFork('mainnet', 18311523);
vm.createSelectFork('mainnet', 18363414);
payload = new PayloadWithEmit();
GovHelpers.executePayload(vm, LONG_PROPOSAL, AaveGovernanceV2.LONG_EXECUTOR);
GovHelpers.passVoteAndExecute(vm, LONG_PROPOSAL_ID);
GovHelpers.executePayload(vm, SHORT_PROPOSAL, AaveGovernanceV2.SHORT_EXECUTOR);
}

Expand Down Expand Up @@ -93,9 +95,9 @@ contract GovernanceV3Test is Test {
GovV3StorageHelpers.readyPayloadId(vm, payloadsController, payloadId);
IPayloadsControllerCore.Payload memory pl = payloadsController.getPayloadById(payloadId);
assertEq(uint256(pl.state), uint256(IPayloadsControllerCore.PayloadState.Queued));
assertEq(pl.queuedAt, 1696751266);
assertEq(pl.queuedAt, 1697983463);
assertEq(uint256(pl.maximumAccessLevelRequired), 1);
assertEq(pl.createdAt, 1696837667);
assertEq(pl.createdAt, 1698069864);
assertEq(pl.creator, address(0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496));
}

Expand Down Expand Up @@ -146,4 +148,8 @@ contract GovernanceV3Test is Test {
GovV3Helpers.createProposal(payloads, 'hash');
vm.stopPrank();
}

function test_helpers() public {
defaultTest('default', AaveV3Ethereum.POOL, address(payload));
}
}
1 change: 1 addition & 0 deletions tests/ProtocolV3TestBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {ProtocolV3LegacyTestBase, ProtocolV3TestBase, ReserveConfig} from '../sr
import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol';
import {AaveV3Polygon, AaveV3PolygonAssets} from 'aave-address-book/AaveV3Polygon.sol';
import {AaveV3Optimism, AaveV3OptimismAssets} from 'aave-address-book/AaveV3Optimism.sol';
import {PayloadWithEmit} from './mocks/PayloadWithEmit.sol';

contract ProtocolV3TestBaseTest is ProtocolV3TestBase {
function setUp() public {
Expand Down