From 665b480ab89a62b0b3b9dbab21479292b3142772 Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 19 Nov 2024 21:28:24 +0100 Subject: [PATCH] feat: update to use new proxy & change stata naming (#75) --- certora/stata/harness/StataTokenV2Harness.sol | 2 +- lib/solidity-utils | 2 +- .../stata-token/StataTokenFactory.sol | 20 ++++++----- .../interfaces/IStataTokenFactory.sol | 27 +++++++++++++++ .../procedures/AaveV3HelpersProcedureTwo.sol | 4 +-- .../procedures/AaveV3SetupProcedure.sol | 14 ++++---- .../procedures/AaveV3TreasuryProcedure.sol | 5 ++- src/deployments/interfaces/IProxyAdmin.sol | 34 ------------------- .../batches/AaveV3PeripheryBatch.sol | 6 ++-- .../stata-token/StataTokenV2Getters.sol | 4 +-- .../stata-token/StataTokenV2Rescuable.sol | 2 -- tests/extensions/stata-token/TestBase.sol | 8 ----- 12 files changed, 56 insertions(+), 72 deletions(-) delete mode 100644 src/deployments/interfaces/IProxyAdmin.sol diff --git a/certora/stata/harness/StataTokenV2Harness.sol b/certora/stata/harness/StataTokenV2Harness.sol index 8b61aec7..1c552930 100644 --- a/certora/stata/harness/StataTokenV2Harness.sol +++ b/certora/stata/harness/StataTokenV2Harness.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.10; import {IERC20} from 'openzeppelin-contracts/contracts/interfaces/IERC20.sol'; -import {StataTokenV2, IPool, IRewardsController} from '../munged/src/contracts/extensions/static-a-token/StataTokenV2.sol'; +import {StataTokenV2, IPool, IRewardsController} from '../munged/src/contracts/extensions/stata-token/StataTokenV2.sol'; import {SymbolicLendingPool} from './pool/SymbolicLendingPool.sol'; contract StataTokenV2Harness is StataTokenV2 { diff --git a/lib/solidity-utils b/lib/solidity-utils index b3c5def7..55d9b81d 160000 --- a/lib/solidity-utils +++ b/lib/solidity-utils @@ -1 +1 @@ -Subproject commit b3c5def7c72b1fc9a1d20e7f2b67feb55e652a06 +Subproject commit 55d9b81d2ea8b0a78b85a46b343f64a979f543da diff --git a/src/contracts/extensions/stata-token/StataTokenFactory.sol b/src/contracts/extensions/stata-token/StataTokenFactory.sol index 5ca2bb28..3de7890a 100644 --- a/src/contracts/extensions/stata-token/StataTokenFactory.sol +++ b/src/contracts/extensions/stata-token/StataTokenFactory.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.10; import {IERC20Metadata} from 'solidity-utils/contracts/oz-common/interfaces/IERC20Metadata.sol'; -import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol'; +import {ITransparentProxyFactory, ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol'; import {Initializable} from 'solidity-utils/contracts/transparent-proxy/Initializable.sol'; import {IPool, DataTypes} from '../../../contracts/interfaces/IPool.sol'; import {StataTokenV2} from './StataTokenV2.sol'; @@ -16,9 +16,16 @@ import {IStataTokenFactory} from './interfaces/IStataTokenFactory.sol'; * @author BGD labs */ contract StataTokenFactory is Initializable, IStataTokenFactory { + ///@inheritdoc IStataTokenFactory IPool public immutable POOL; + + ///@inheritdoc IStataTokenFactory address public immutable PROXY_ADMIN; + + ///@inheritdoc IStataTokenFactory ITransparentProxyFactory public immutable TRANSPARENT_PROXY_FACTORY; + + ///@inheritdoc IStataTokenFactory address public immutable STATA_TOKEN_IMPL; mapping(address => address) internal _underlyingToStataToken; @@ -50,19 +57,16 @@ contract StataTokenFactory is Initializable, IStataTokenFactory { if (reserveData.aTokenAddress == address(0)) revert NotListedUnderlying(reserveData.aTokenAddress); bytes memory symbol = abi.encodePacked( - 'stat', - IERC20Metadata(reserveData.aTokenAddress).symbol(), - 'v2' + 'w', + IERC20Metadata(reserveData.aTokenAddress).symbol() ); address stataToken = TRANSPARENT_PROXY_FACTORY.createDeterministic( STATA_TOKEN_IMPL, - PROXY_ADMIN, + ProxyAdmin(PROXY_ADMIN), abi.encodeWithSelector( StataTokenV2.initialize.selector, reserveData.aTokenAddress, - string( - abi.encodePacked('Static ', IERC20Metadata(reserveData.aTokenAddress).name(), ' v2') - ), + string(abi.encodePacked('Wrapped ', IERC20Metadata(reserveData.aTokenAddress).name())), string(symbol) ), bytes32(uint256(uint160(underlyings[i]))) diff --git a/src/contracts/extensions/stata-token/interfaces/IStataTokenFactory.sol b/src/contracts/extensions/stata-token/interfaces/IStataTokenFactory.sol index 2eaf187b..5566d023 100644 --- a/src/contracts/extensions/stata-token/interfaces/IStataTokenFactory.sol +++ b/src/contracts/extensions/stata-token/interfaces/IStataTokenFactory.sol @@ -1,9 +1,36 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; +import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol'; +import {IPool, IPoolAddressesProvider} from '../../../interfaces/IPool.sol'; + interface IStataTokenFactory { error NotListedUnderlying(address underlying); + /** + * @notice The pool associated with the factory. + * @return The pool address. + */ + function POOL() external view returns (IPool); + + /** + * @notice The proxy admin used for all tokens created via the factory. + * @return The proxy admin address. + */ + function PROXY_ADMIN() external view returns (address); + + /** + * @notice The proxy factory used for all tokens created via the stata factory. + * @return The proxy factory address. + */ + function TRANSPARENT_PROXY_FACTORY() external view returns (ITransparentProxyFactory); + + /** + * @notice The stata implementation used for all tokens created via the factory. + * @return The implementation address. + */ + function STATA_TOKEN_IMPL() external view returns (address); + /** * @notice Creates new StataTokens * @param underlyings the addresses of the underlyings to create. diff --git a/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol b/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol index 99a9b5a1..12890f5d 100644 --- a/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol +++ b/src/deployments/contracts/procedures/AaveV3HelpersProcedureTwo.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import '../../interfaces/IMarketReportTypes.sol'; -import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol'; +import {ITransparentProxyFactory, ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol'; import {TransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/TransparentProxyFactory.sol'; import {StataTokenV2} from '../../../contracts/extensions/stata-token/StataTokenV2.sol'; import {StataTokenFactory} from '../../../contracts/extensions/stata-token/StataTokenFactory.sol'; @@ -33,7 +33,7 @@ contract AaveV3HelpersProcedureTwo is IErrors { staticATokenReport.transparentProxyFactory ).create( staticATokenReport.staticATokenFactoryImplementation, - proxyAdmin, + ProxyAdmin(proxyAdmin), abi.encodeWithSelector(StataTokenFactory.initialize.selector) ); diff --git a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol index 481bbd5d..8e6357fe 100644 --- a/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3SetupProcedure.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import '../../interfaces/IMarketReportTypes.sol'; -import {IOwnable} from 'solidity-utils/contracts/transparent-proxy/interfaces/IOwnable.sol'; +import {Ownable} from '../../../contracts/dependencies/openzeppelin/contracts/Ownable.sol'; import {ACLManager} from '../../../contracts/protocol/configuration/ACLManager.sol'; import {IPoolConfigurator} from '../../../contracts/interfaces/IPoolConfigurator.sol'; import {IPoolAddressesProvider} from '../../../contracts/interfaces/IPoolAddressesProvider.sol'; @@ -99,7 +99,7 @@ contract AaveV3SetupProcedure { poolAddressesProvider, providerId ); - IOwnable(poolAddressesProviderRegistry).transferOwnership(marketOwner); + Ownable(poolAddressesProviderRegistry).transferOwnership(marketOwner); } else { poolAddressesProviderRegistry = providerRegistry; } @@ -137,7 +137,7 @@ contract AaveV3SetupProcedure { IRewardsController(report.rewardsControllerProxy).EMISSION_MANAGER() ); emissionManager.setRewardsController(report.rewardsControllerProxy); - IOwnable(address(emissionManager)).transferOwnership(input.poolAdmin); + Ownable(address(emissionManager)).transferOwnership(input.poolAdmin); } else { provider.setAddress(controllerId, input.rewardsControllerProxy); report.rewardsControllerProxy = provider.getAddress(controllerId); @@ -199,15 +199,15 @@ contract AaveV3SetupProcedure { } function _transferMarketOwnership(Roles memory roles, InitialReport memory report) internal { - address addressesProviderOwner = IOwnable(report.poolAddressesProvider).owner(); - address marketOwner = IOwnable(report.poolAddressesProviderRegistry).owner(); + address addressesProviderOwner = Ownable(report.poolAddressesProvider).owner(); + address marketOwner = Ownable(report.poolAddressesProviderRegistry).owner(); if (addressesProviderOwner == address(this)) { - IOwnable(report.poolAddressesProvider).transferOwnership(roles.marketOwner); + Ownable(report.poolAddressesProvider).transferOwnership(roles.marketOwner); } if (marketOwner == address(this)) { - IOwnable(report.poolAddressesProviderRegistry).transferOwnership(roles.marketOwner); + Ownable(report.poolAddressesProviderRegistry).transferOwnership(roles.marketOwner); } } diff --git a/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol b/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol index f904f559..76f6650b 100644 --- a/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol +++ b/src/deployments/contracts/procedures/AaveV3TreasuryProcedure.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.0; import {ProxyAdmin} from 'solidity-utils/contracts/transparent-proxy/ProxyAdmin.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; -import {IOwnable} from 'solidity-utils/contracts/transparent-proxy/interfaces/IOwnable.sol'; import {Collector} from '../../../contracts/treasury/Collector.sol'; import '../../interfaces/IMarketReportTypes.sol'; @@ -30,7 +29,7 @@ contract AaveV3TreasuryProcedure { treasuryReport.treasury = address( new TransparentUpgradeableProxy{salt: salt}( treasuryReport.treasuryImplementation, - deployedProxyAdmin, + ProxyAdmin(deployedProxyAdmin), abi.encodeWithSelector( treasuryImplementation.initialize.selector, address(treasuryOwner), @@ -46,7 +45,7 @@ contract AaveV3TreasuryProcedure { treasuryReport.treasury = address( new TransparentUpgradeableProxy( treasuryReport.treasuryImplementation, - deployedProxyAdmin, + ProxyAdmin(deployedProxyAdmin), abi.encodeWithSelector( treasuryImplementation.initialize.selector, address(treasuryOwner), diff --git a/src/deployments/interfaces/IProxyAdmin.sol b/src/deployments/interfaces/IProxyAdmin.sol deleted file mode 100644 index 819ad7f9..00000000 --- a/src/deployments/interfaces/IProxyAdmin.sol +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @dev OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol) - * From https://github.com/OpenZeppelin/openzeppelin-contracts/tree/8b778fa20d6d76340c5fac1ed66c80273f05b95a - * - * BGD Labs adaptations: - * - Linting - */ - -pragma solidity ^0.8.0; - -import 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; -import 'solidity-utils/contracts/transparent-proxy/interfaces/IOwnable.sol'; - -/** - * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an - * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}. - */ -interface IProxyAdmin is IOwnable { - function getProxyImplementation( - TransparentUpgradeableProxy proxy - ) external view returns (address); - - function getProxyAdmin(TransparentUpgradeableProxy proxy) external view returns (address); - - function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) external; - - function upgrade(TransparentUpgradeableProxy proxy, address implementation) external; - - function upgradeAndCall( - TransparentUpgradeableProxy proxy, - address implementation, - bytes memory data - ) external payable; -} diff --git a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol index bf02940b..ce332dfe 100644 --- a/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol +++ b/src/deployments/projects/aave-v3-batched/batches/AaveV3PeripheryBatch.sol @@ -5,10 +5,9 @@ import {AaveV3TreasuryProcedure} from '../../../contracts/procedures/AaveV3Treas import {AaveV3OracleProcedure} from '../../../contracts/procedures/AaveV3OracleProcedure.sol'; import {AaveV3IncentiveProcedure} from '../../../contracts/procedures/AaveV3IncentiveProcedure.sol'; import {AaveV3DefaultRateStrategyProcedure} from '../../../contracts/procedures/AaveV3DefaultRateStrategyProcedure.sol'; -import {IOwnable} from 'solidity-utils/contracts/transparent-proxy/interfaces/IOwnable.sol'; +import {Ownable} from '../../../../contracts/dependencies/openzeppelin/contracts/Ownable.sol'; import '../../../interfaces/IMarketReportTypes.sol'; import {IRewardsController} from '../../../../contracts/rewards/interfaces/IRewardsController.sol'; -import {IOwnable} from 'solidity-utils/contracts/transparent-proxy/interfaces/IOwnable.sol'; import {RevenueSplitter} from '../../../../contracts/treasury/RevenueSplitter.sol'; contract AaveV3PeripheryBatch is @@ -25,8 +24,7 @@ contract AaveV3PeripheryBatch is address setupBatch ) { if (config.proxyAdmin == address(0)) { - _report.proxyAdmin = address(new ProxyAdmin{salt: config.salt}()); - IOwnable(_report.proxyAdmin).transferOwnership(poolAdmin); + _report.proxyAdmin = address(new ProxyAdmin{salt: config.salt}(poolAdmin)); } else { _report.proxyAdmin = config.proxyAdmin; } diff --git a/tests/extensions/stata-token/StataTokenV2Getters.sol b/tests/extensions/stata-token/StataTokenV2Getters.sol index 4e151c27..c329b247 100644 --- a/tests/extensions/stata-token/StataTokenV2Getters.sol +++ b/tests/extensions/stata-token/StataTokenV2Getters.sol @@ -16,8 +16,8 @@ contract StataTokenV2GettersTest is BaseTest { } function test_getters() public view { - assertEq(stataTokenV2.name(), 'Static Aave Local WETH v2'); - assertEq(stataTokenV2.symbol(), 'stataLocWETHv2'); + assertEq(stataTokenV2.name(), 'Wrapped Aave Local WETH'); + assertEq(stataTokenV2.symbol(), 'waLocWETH'); address referenceAsset = stataTokenV2.getReferenceAsset(); assertEq(referenceAsset, aToken); diff --git a/tests/extensions/stata-token/StataTokenV2Rescuable.sol b/tests/extensions/stata-token/StataTokenV2Rescuable.sol index 652e72f1..e8ccad49 100644 --- a/tests/extensions/stata-token/StataTokenV2Rescuable.sol +++ b/tests/extensions/stata-token/StataTokenV2Rescuable.sol @@ -44,8 +44,6 @@ contract StataTokenV2RescuableTest is BaseTest { _fundAToken(donation, address(stataTokenV2)); _fund4626(stake, address(this)); - address treasury = IAToken(aToken).RESERVE_TREASURY_ADDRESS(); - vm.expectEmit(true, true, true, true); emit ERC20Rescued(poolAdmin, aToken, address(this), donation); vm.startPrank(poolAdmin); diff --git a/tests/extensions/stata-token/TestBase.sol b/tests/extensions/stata-token/TestBase.sol index 36457337..e7cfab41 100644 --- a/tests/extensions/stata-token/TestBase.sol +++ b/tests/extensions/stata-token/TestBase.sol @@ -64,14 +64,6 @@ abstract contract BaseTest is TestnetProcedures { vm.warp(block.timestamp + blocks * 12); // assuming a block is around 12seconds } - function testAdmin() public { - vm.stopPrank(); - vm.startPrank(proxyAdmin); - assertEq(TransparentUpgradeableProxy(payable(address(stataTokenV2))).admin(), proxyAdmin); - assertEq(TransparentUpgradeableProxy(payable(address(factory))).admin(), proxyAdmin); - vm.stopPrank(); - } - function _fundUnderlying(uint256 assets, address receiver) internal { deal(underlying, receiver, assets); }