Skip to content
Open
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
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# include .env file and export its env vars
# (-include to ignore error if it does not exist)
-include .env

# deps
update:; forge update

# Build & test
build :; forge build --sizes
test :; forge test -vvv

test-contract :; forge test --match-contract ${filter} -vv

# Deploy
deploy-ledger-zk :; FOUNDRY_PROFILE=zksync forge script $(if $(filter zksync,${chain}),--zksync) ${contract} --rpc-url ${chain} $(if ${dry},--sender 0x73AF3bcf944a6559933396c1577B257e2054D935 -vvvv, --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv --slow --broadcast --verifier etherscan)
deploy-ledger :; forge script $(if $(filter zksync,${chain}),--zksync) ${contract} --rpc-url ${chain} $(if ${dry},--sender 0x73AF3bcf944a6559933396c1577B257e2054D935 -vvvv, --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv --slow --broadcast) $(if ${legacy}, --legacy, )
deploy-pk :; forge script $(if $(filter zksync,${chain}),--zksync) ${contract} --rpc-url ${chain} $(if ${dry},--sender 0x73AF3bcf944a6559933396c1577B257e2054D935 -vvvv, --private-key ${PRIVATE_KEY} --verify -vvvv --slow --broadcast)

# Utilities
download :; cast etherscan-source --chain ${chain} -d src/etherscan/${chain}_${address} ${address}
git-diff :
@mkdir -p diffs
@npx prettier ${before} ${after} --write
@printf '%s\n%s\n%s\n' "\`\`\`diff" "$$(git diff --no-index --diff-algorithm=patience --ignore-space-at-eol ${before} ${after})" "\`\`\`" > diffs/${out}.md
170 changes: 170 additions & 0 deletions broadcast/Deploy.s.sol/1/run-1755787670770.json

Large diffs are not rendered by default.

170 changes: 170 additions & 0 deletions broadcast/Deploy.s.sol/1/run-latest.json

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions foundry.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"lib/aave-helpers": {
"rev": "742d98403699196c95bd36ae5925b9610dcb6bff"
},
"lib/forge-std": {
"rev": "1eea5bae12ae557d589f9f0f0edae2faa47cb262"
}
}
5 changes: 5 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
src = "src"
out = "out"
libs = ["lib"]
optimizer = true
optimizer_runs = 200
solc = '0.8.27'
evm_version = 'shanghai'
bytecode_hash = 'none'

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
[rpc_endpoints]
Expand Down
2 changes: 1 addition & 1 deletion lib/aave-helpers
Submodule aave-helpers updated 92 files
+3 −3 .github/dependabot.yml
+11 −41 .github/workflows/merge-main.yml
+4 −2 .gitignore
+1 −1 .gitmodules
+7 −0 .prettierignore
+145 −165 CHANGELOG.md
+20 −1 diffs/AMMTEST_before_AMMTEST_after.md
+1 −1 diffs/adi_test_adi_diffs_before_adi_test_adi_diffs_after.md
+20 −3 diffs/default_before_default_after.md
+8 −8 diffs/preTestV2RatesUpdates_postTestV2RatesUpdates.md
+2 −574 diffs/zksync_before_zksync_after.md
+8 −0 foundry.lock
+18 −8 foundry.toml
+1 −1 lib/aave-address-book
+1 −1 lib/forge-std
+2,229 −0 package-lock.json
+5 −5 package.json
+3 −8 scripts/AaveSwapperDeployment.s.sol
+0 −22 scripts/AaveWstethWithdrawerDeployment.s.sol
+1 −1 scripts/DeployBridges.s.sol
+0 −7 scripts/FreezingStewards.s.sol
+0 −12 scripts/RiskStewards.s.sol
+3 −2 scripts/V2RateStrategyFactory.s.sol
+0 −4 src/ChainIds.sol
+8 −11 src/CollectorUtils.sol
+32 −2 src/CommonTestBase.sol
+221 −11 src/GovV3Helpers.sol
+1 −1 src/IpfsUtils.sol
+57 −10 src/ProtocolV2TestBase.sol
+453 −257 src/ProtocolV3TestBase.sol
+33 −0 src/SeatbeltUtils.sol
+0 −114 src/asset-manager/AaveWstethWithdrawer.sol
+0 −14 src/asset-manager/Common.sol
+0 −41 src/asset-manager/LSDLiquidityGaugeManager.sol
+0 −192 src/asset-manager/README.md
+0 −42 src/asset-manager/StrategicAssetsManager.sol
+0 −224 src/asset-manager/VeTokenManager.sol
+0 −72 src/asset-manager/VlTokenManager.sol
+ src/asset-manager/images/AaveWstethWithdrawer.png
+0 −74 src/asset-manager/interfaces/IAaveWstethWithdrawer.sol
+0 −16 src/asset-manager/interfaces/IDelegateRegistry.sol
+0 −12 src/asset-manager/interfaces/ILiquidityGaugeController.sol
+0 −27 src/asset-manager/interfaces/IVeToken.sol
+0 −45 src/asset-manager/interfaces/IVlToken.sol
+0 −90 src/asset-manager/interfaces/IWardenBoost.sol
+6 −8 src/bridges/arbitrum/AaveArbEthERC20Bridge.sol
+6 −8 src/bridges/optimism/AaveOpEthERC20Bridge.sol
+6 −8 src/bridges/polygon/AavePolEthERC20Bridge.sol
+6 −8 src/bridges/polygon/AavePolEthPlasmaBridge.sol
+1 −1 src/dependencies/DefaultReserveInterestRateStrategy.sol
+6 −0 src/dependencies/IPermissionedPayloadsController.sol
+1 −1 src/riskstewards/CapsPlusRiskSteward.sol
+0 −1 src/riskstewards/ICapsPlusRiskSteward.sol
+11 −11 src/swaps/AaveSwapper.sol
+2 −2 src/swaps/BaseSwapPayload.sol
+2 −2 src/swaps/DepositV2SwapPayload.sol
+2 −2 src/swaps/DepositV3SwapPayload.sol
+0 −3 src/swaps/interfaces/IAaveSwapper.sol
+1 −1 src/swaps/interfaces/IMilkman.sol
+1 −1 src/v2-config-engine/AaveV2Payload.sol
+1 −1 src/v2-config-engine/V2RateStrategyFactory.sol
+15 −0 src/v3-config-engine/AaveV3PayloadCelo.sol
+17 −0 src/v3-config-engine/AaveV3PayloadInkWhitelabel.sol
+15 −0 src/v3-config-engine/AaveV3PayloadLinea.sol
+15 −0 src/v3-config-engine/AaveV3PayloadMantle.sol
+0 −17 src/v3-config-engine/AaveV3PayloadPolygonZkEvm.sol
+15 −0 src/v3-config-engine/AaveV3PayloadSoneium.sol
+15 −0 src/v3-config-engine/AaveV3PayloadSonic.sol
+7 −5 tests/CollectorUtils.t.sol
+25 −8 tests/GovV3Test.t.sol
+1 −1 tests/ProtocolV2TestBase.t.sol
+27 −20 tests/ProtocolV3TestBase.t.sol
+2 −2 tests/ProxyHelpersTest.t.sol
+0 −287 tests/asset-manager/AaveWstethWithdrawerTest.t.sol
+0 −120 tests/asset-manager/TestLSDLiquidityGaugeManager.t.sol
+0 −125 tests/asset-manager/TestStrategicAssetsManager.t.sol
+0 −529 tests/asset-manager/TestVeTokenManager.t.sol
+0 −251 tests/asset-manager/TestVlTokenManager.t.sol
+11 −7 tests/bridges/arbitrum/AaveArbEthERC20BridgeTest.t.sol
+6 −6 tests/bridges/arbitrum/ArbSysMock.sol
+10 −5 tests/bridges/optimism/AaveOpEthERC20BridgeTest.t.sol
+13 −7 tests/bridges/polygon/AavePolEthERC20BridgeTest.t.sol
+12 −9 tests/bridges/polygon/AavePolEthPlasmaBridge.t.sol
+1 −1 tests/riskstewards/CapsPlusRiskSteward.t.sol
+35 −28 tests/swaps/AaveSwapperTest.t.sol
+1 −1 tests/swaps/DepositV2SwapPayloadTest.t.sol
+1 −1 tests/swaps/DepositV3SwapPayloadTest.t.sol
+2 −2 tests/v2-config-engine/AaveV2ConfigEngineTest.t.sol
+0 −1,041 yarn.lock
+104 −289 zksync/src/ProtocolV3TestBase.sol
+56 −118 zksync/src/SnapshotHelpersV3.sol
+22 −0 zksync/tests/ProtocolV3TestBase.t.sol
51 changes: 33 additions & 18 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,18 @@ import {IPoolAddressesProvider} from "aave-v3-origin/contracts/interfaces/IPoolA
import {ICollector} from "aave-v3-origin/contracts/treasury/ICollector.sol";
import {ITransparentProxyFactory} from
"solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol";
import {IProxyAdminOzV4} from "solidity-utils/contracts/transparent-proxy/interfaces/IProxyAdminOzV4.sol";
import {GhoDirectMinter} from "../src/GhoDirectMinter.sol";
import {IGhoToken} from "../src/interfaces/IGhoToken.sol";

import {AaveV3EthereumAssets} from "aave-address-book/AaveV3Ethereum.sol";
import {AaveV3Ethereum, AaveV3EthereumAssets} from "aave-address-book/AaveV3Ethereum.sol";
import {AaveV3EthereumLido} from "aave-address-book/AaveV3EthereumLido.sol";
import {GovernanceV3Ethereum} from "aave-address-book/GovernanceV3Ethereum.sol";
import {MiscEthereum} from "aave-address-book/MiscEthereum.sol";

library DeploymentLibrary {
function _deployFacilitator(
ITransparentProxyFactory proxyFactory,
address proxyAdmin,
address upgradeAdmin,
IPoolAddressesProvider poolAddressesProvider,
address collector,
IGhoToken gho,
Expand All @@ -27,30 +26,46 @@ library DeploymentLibrary {
address vaultImpl = address(new GhoDirectMinter(poolAddressesProvider, address(collector), address(gho)));
return proxyFactory.create(
vaultImpl,
proxyAdmin,
upgradeAdmin,
abi.encodeWithSelector(GhoDirectMinter.initialize.selector, address(GovernanceV3Ethereum.EXECUTOR_LVL_1), council)
);
}

function _deployLido() internal returns (address) {
// its the council used on other GHO stewards
// might make sense to have on address book
function _deployCore() internal returns (address) {
address council = 0x8513e6F37dBc52De87b166980Fa3F50639694B60;
return _deployFacilitator(
//ITransparentProxyFactory(MiscEthereum.TRANSPARENT_PROXY_FACTORY),
// using an old TRANSPARENT_PROXY_FACTORY, it was replaced in a new version of aave-address-book
ITransparentProxyFactory(0x9FB3B12248bf010AEA7cE08343C8499FFAB4770f),
MiscEthereum.PROXY_ADMIN,
AaveV3EthereumLido.POOL_ADDRESSES_PROVIDER,
address(AaveV3EthereumLido.COLLECTOR),
IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING),
council

return ITransparentProxyFactory(MiscEthereum.TRANSPARENT_PROXY_FACTORY).create(
0xE4C958dE49303c9be571E00582CF9454586dE76F,
GovernanceV3Ethereum.EXECUTOR_LVL_1,
abi.encodeWithSelector(GhoDirectMinter.initialize.selector, address(GovernanceV3Ethereum.EXECUTOR_LVL_1), council)
);
}

// function _deployLido() internal returns (address) {
// // its the council used on other GHO stewards
// // might make sense to have on address book
// address council = 0x8513e6F37dBc52De87b166980Fa3F50639694B60;
// return _deployFacilitator(
// //ITransparentProxyFactory(MiscEthereum.TRANSPARENT_PROXY_FACTORY),
// // using an old TRANSPARENT_PROXY_FACTORY, it was replaced in a new version of aave-address-book
// ITransparentProxyFactory(0x9FB3B12248bf010AEA7cE08343C8499FFAB4770f),
// MiscEthereum.PROXY_ADMIN,
// AaveV3EthereumLido.POOL_ADDRESSES_PROVIDER,
// address(AaveV3EthereumLido.COLLECTOR),
// IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING),
// council
// );
// }
}

contract DeployLido is EthereumScript {
// contract DeployLido is EthereumScript {
// function run() external broadcast {
// DeploymentLibrary._deployLido();
// }
// }
//
contract DeployCore is EthereumScript {
function run() external broadcast {
DeploymentLibrary._deployLido();
DeploymentLibrary._deployCore();
}
}
48 changes: 0 additions & 48 deletions src/proposals/LidoGHOListing.sol

This file was deleted.

60 changes: 32 additions & 28 deletions test/Lido_GhoDirectMinter.t.sol → test/GhoDirectMinter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import {MiscEthereum} from "aave-address-book/MiscEthereum.sol";
import {AaveV3EthereumAssets} from "aave-address-book/AaveV3Ethereum.sol";
import {AaveV3Ethereum, AaveV3EthereumAssets, IACLManager} from "aave-address-book/AaveV3Ethereum.sol";
import {AaveV3EthereumLido} from "aave-address-book/AaveV3EthereumLido.sol";
import {GovernanceV3Ethereum} from "aave-address-book/GovernanceV3Ethereum.sol";
import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
Expand All @@ -13,50 +13,52 @@ import {
UpgradeableOwnableWithGuardian,
IWithGuardian
} from "solidity-utils/contracts/access-control/UpgradeableOwnableWithGuardian.sol";
import {IAccessControl} from "openzeppelin-contracts/contracts/access/IAccessControl.sol";
import {GovV3Helpers} from "aave-helpers/src/GovV3Helpers.sol";
import {IPool, DataTypes} from "aave-v3-origin/contracts/interfaces/IPool.sol";
import {ReserveConfiguration} from "aave-v3-origin/contracts/protocol/libraries/configuration/ReserveConfiguration.sol";
import {GhoDirectMinter} from "../src/GhoDirectMinter.sol";
import {LidoGHOListing} from "../src/proposals/LidoGHOListing.sol";
import {IGhoToken} from "../src/interfaces/IGhoToken.sol";
import {DeploymentLibrary} from "../script/Deploy.s.sol";

contract Lido_GHODirectMinter_Test is Test {
contract GHODirectMinter_Test is Test {
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;

// its the council used on other GHO stewards
// might make sense to have on address book
address council = 0x8513e6F37dBc52De87b166980Fa3F50639694B60;

GhoDirectMinter internal minter;
uint128 internal constant MINT_AMOUNT = 200_000 ether;
IERC20 internal ghoAToken;
LidoGHOListing internal proposal;

address owner = GovernanceV3Ethereum.EXECUTOR_LVL_1;

function setUp() external {
vm.createSelectFork(vm.rpcUrl("mainnet"), 21378878);
vm.createSelectFork(vm.rpcUrl("mainnet"), 23189945);

// execute pending gho listing payload
GovV3Helpers.executePayload(vm, 218);

// execute payload
address facilitator = DeploymentLibrary._deployLido();
proposal = new LidoGHOListing(facilitator);
GovV3Helpers.executePayload(vm, address(proposal));
// list facilitator
minter = GhoDirectMinter(DeploymentLibrary._deployCore());
vm.startPrank(owner);
IAccessControl(address(getACL())).grantRole(getACL().RISK_ADMIN_ROLE(), address(minter));
IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).addFacilitator(address(minter), "minter", MINT_AMOUNT);

address[] memory facilitators = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorsList();
minter = GhoDirectMinter(facilitators[facilitators.length - 1]);
assertEq(address(minter), facilitator);
assertEq(facilitators[facilitators.length - 1], address(minter));
ghoAToken = IERC20(minter.GHO_A_TOKEN());

// burn all supply to start with a clean state on the tests
uint256 totalATokenSupply = ghoAToken.totalSupply();
uint128 mintAmount = proposal.GHO_MINT_AMOUNT();
vm.prank(owner);
minter.withdrawAndBurn(mintAmount);
assertEq(ghoAToken.balanceOf(address(minter)), 0);
assertEq(ghoAToken.totalSupply(), totalATokenSupply - mintAmount);
vm.stopPrank();
}

function getPool() internal view returns (IPool) {
return AaveV3Ethereum.POOL;
}

function getACL() internal view returns (IACLManager) {
return AaveV3Ethereum.ACL_MANAGER;
}

function test_mintAndSupply_owner(uint256 amount) public returns (uint256) {
Expand Down Expand Up @@ -91,14 +93,18 @@ contract Lido_GHODirectMinter_Test is Test {
deal(AaveV3EthereumAssets.wstETH_UNDERLYING, address(this), 1_000 ether);
IERC20(AaveV3EthereumAssets.wstETH_UNDERLYING).approve(address(AaveV3EthereumLido.POOL), 1_000 ether);
AaveV3EthereumLido.POOL.deposit(AaveV3EthereumAssets.wstETH_UNDERLYING, 1_000 ether, address(this), 0);
vm.prank(owner);
AaveV3EthereumLido.POOL_CONFIGURATOR.setBorrowCap(AaveV3EthereumAssets.GHO_UNDERLYING, 0);
AaveV3EthereumLido.POOL.borrow(AaveV3EthereumAssets.GHO_UNDERLYING, amount, 2, 0, address(this));

// generate some yield
vm.warp(block.timestamp + 1000);

uint256 collectorBalanceBeforeTransfer = ghoAToken.balanceOf(address(minter.COLLECTOR()));
uint256 balanceBeforeTransfer = ghoAToken.balanceOf(address(minter));
assertGt(balanceBeforeTransfer, amount);
// is equal on core due to rf 100%
// is gt on lido due to ef < 100%
assertGe(balanceBeforeTransfer, amount);
minter.transferExcessToTreasury();
assertApproxEqAbs(ghoAToken.balanceOf(address(minter)), amount, 1);
assertApproxEqAbs(
Expand All @@ -111,22 +117,21 @@ contract Lido_GHODirectMinter_Test is Test {
/// @dev supplies a bounded value of [amount, 1, type(uint256).max] to the pool
function _mintAndSupply(uint256 amount, address caller) internal returns (uint256) {
// setup
amount = bound(amount, 1, proposal.GHO_MINT_AMOUNT());
amount = bound(amount, 1, MINT_AMOUNT);
DataTypes.ReserveConfigurationMap memory configurationBefore =
AaveV3EthereumLido.POOL.getConfiguration(AaveV3EthereumAssets.GHO_UNDERLYING);
getPool().getConfiguration(AaveV3EthereumAssets.GHO_UNDERLYING);
uint256 totalATokenSupplyBefore = ghoAToken.totalSupply();
uint256 minterATokenSupplyBefore = IERC20(ghoAToken).balanceOf(address(minter));
(, uint256 levelBefore) =
IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorBucket(proposal.FACILITATOR());
(, uint256 levelBefore) = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorBucket(address(minter));

// mint
vm.prank(caller);
minter.mintAndSupply(amount);

// check
DataTypes.ReserveConfigurationMap memory configurationAfter =
AaveV3EthereumLido.POOL.getConfiguration(AaveV3EthereumAssets.GHO_UNDERLYING);
(, uint256 levelAfter) = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorBucket(proposal.FACILITATOR());
getPool().getConfiguration(AaveV3EthereumAssets.GHO_UNDERLYING);
(, uint256 levelAfter) = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorBucket(address(minter));
// after supplying the minters aToken balance should increase by the supplied amount
assertEq(IERC20(ghoAToken).balanceOf(address(minter)), minterATokenSupplyBefore + amount);
// the aToken total supply should be adjusted by the same amount
Expand All @@ -144,15 +149,14 @@ contract Lido_GHODirectMinter_Test is Test {
uint256 amount = _mintAndSupply(supplyAmount, owner);
withdrawAmount = bound(withdrawAmount, 1, amount);
uint256 totalATokenSupplyBefore = ghoAToken.totalSupply();
(, uint256 levelBefore) =
IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorBucket(proposal.FACILITATOR());
(, uint256 levelBefore) = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorBucket(address(minter));

// burn
vm.prank(caller);
minter.withdrawAndBurn(withdrawAmount);

// check
(, uint256 levelAfter) = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorBucket(proposal.FACILITATOR());
(, uint256 levelAfter) = IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).getFacilitatorBucket(address(minter));
// aToken total supply should be decreased by the burned amount
assertEq(ghoAToken.totalSupply(), totalATokenSupplyBefore - withdrawAmount);
// the minter supply should shrink by the same amount
Expand Down
Loading