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

Add config.incentivesProxy to reuse RewardsController proxy across instances in same EVM network #48

Merged
merged 4 commits into from
Aug 21, 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
79 changes: 49 additions & 30 deletions src/deployments/contracts/procedures/AaveV3SetupProcedure.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ import {IEmissionManager} from 'aave-v3-periphery/contracts/rewards/interfaces/I
import {IRewardsController} from 'aave-v3-periphery/contracts/rewards/interfaces/IRewardsController.sol';

contract AaveV3SetupProcedure {
struct AddressProviderInput {
InitialReport initialReport;
address poolImplementation;
address poolConfiguratorImplementation;
address protocolDataProvider;
address poolAdmin;
address aaveOracle;
address rewardsControllerProxy;
address rewardsControllerImplementation;
address priceOracleSentinel;
}

function _initialDeployment(
address providerRegistry,
address marketOwner,
Expand Down Expand Up @@ -44,14 +56,17 @@ contract AaveV3SetupProcedure {
_validateMarketSetup(roles);

SetupReport memory report = _setupPoolAddressesProvider(
initialReport,
poolImplementation,
poolConfiguratorImplementation,
protocolDataProvider,
roles.poolAdmin,
aaveOracle,
rewardsControllerImplementation,
priceOracleSentinel
AddressProviderInput(
initialReport,
poolImplementation,
poolConfiguratorImplementation,
protocolDataProvider,
roles.poolAdmin,
aaveOracle,
config.incentivesProxy,
rewardsControllerImplementation,
priceOracleSentinel
)
);

report.aclManager = _setupACL(
Expand Down Expand Up @@ -90,38 +105,42 @@ contract AaveV3SetupProcedure {
}

function _setupPoolAddressesProvider(
InitialReport memory initialReport,
address poolImplementation,
address poolConfiguratorImplementation,
address protocolDataProvider,
address poolAdmin,
address aaveOracle,
address rewardsControllerImplementation,
address priceOracleSentinel
AddressProviderInput memory input
) internal returns (SetupReport memory) {
SetupReport memory report;

IPoolAddressesProvider provider = IPoolAddressesProvider(initialReport.poolAddressesProvider);
provider.setPriceOracle(aaveOracle);
provider.setPoolImpl(poolImplementation);
provider.setPoolConfiguratorImpl(poolConfiguratorImplementation);
provider.setPoolDataProvider(protocolDataProvider);
IPoolAddressesProvider provider = IPoolAddressesProvider(
input.initialReport.poolAddressesProvider
);
provider.setPriceOracle(input.aaveOracle);
provider.setPoolImpl(input.poolImplementation);
provider.setPoolConfiguratorImpl(input.poolConfiguratorImplementation);
provider.setPoolDataProvider(input.protocolDataProvider);

report.poolProxy = address(provider.getPool());
report.poolConfiguratorProxy = address(provider.getPoolConfigurator());

if (priceOracleSentinel != address(0)) {
provider.setPriceOracleSentinel(priceOracleSentinel);
if (input.priceOracleSentinel != address(0)) {
provider.setPriceOracleSentinel(input.priceOracleSentinel);
}

bytes32 controllerId = keccak256('INCENTIVES_CONTROLLER');
provider.setAddressAsProxy(controllerId, rewardsControllerImplementation);
report.rewardsControllerProxy = provider.getAddress(controllerId);
IEmissionManager emissionManager = IEmissionManager(
IRewardsController(report.rewardsControllerProxy).EMISSION_MANAGER()
);
emissionManager.setRewardsController(report.rewardsControllerProxy);
IOwnable(address(emissionManager)).transferOwnership(poolAdmin);
if (input.rewardsControllerProxy == address(0)) {
require(
input.rewardsControllerImplementation != address(0),
'rewardsControllerImplementation must be set'
);
provider.setAddressAsProxy(controllerId, input.rewardsControllerImplementation);
report.rewardsControllerProxy = provider.getAddress(controllerId);
IEmissionManager emissionManager = IEmissionManager(
IRewardsController(report.rewardsControllerProxy).EMISSION_MANAGER()
);
emissionManager.setRewardsController(report.rewardsControllerProxy);
IOwnable(address(emissionManager)).transferOwnership(input.poolAdmin);
} else {
provider.setAddress(controllerId, input.rewardsControllerProxy);
report.rewardsControllerProxy = provider.getAddress(controllerId);
}
return report;
}

Expand Down
1 change: 1 addition & 0 deletions src/deployments/interfaces/IMarketReportTypes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ struct MarketConfig {
address proxyAdmin;
uint128 flashLoanPremiumTotal;
uint128 flashLoanPremiumToProtocol;
address incentivesProxy;
}

struct DeployFlags {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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 '../../../interfaces/IMarketReportTypes.sol';

contract AaveV3PeripheryBatch is
Expand All @@ -30,9 +31,13 @@ contract AaveV3PeripheryBatch is
_report.treasury = treasuryReport.treasury;
_report.treasuryImplementation = treasuryReport.treasuryImplementation;

(_report.emissionManager, _report.rewardsControllerImplementation) = _deployIncentives(
setupBatch
);
if (config.incentivesProxy == address(0)) {
(_report.emissionManager, _report.rewardsControllerImplementation) = _deployIncentives(
setupBatch
);
} else {
_report.emissionManager = IRewardsController(config.incentivesProxy).getEmissionManager();
}
}

function getPeripheryReport() external view returns (PeripheryReport memory) {
Expand Down
23 changes: 20 additions & 3 deletions tests/AaveV3BatchDeployment.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {IAaveV3ConfigEngine} from 'aave-v3-periphery/contracts/v3-config-engine/
import {IPool} from 'aave-v3-core/contracts/interfaces/IPool.sol';
import {AaveV3ConfigEngine} from 'aave-v3-periphery/contracts/v3-config-engine/AaveV3ConfigEngine.sol';
import {SequencerOracle} from 'aave-v3-core/contracts/mocks/oracle/SequencerOracle.sol';
import {RewardsController} from 'aave-v3-periphery/contracts/rewards/RewardsController.sol';
import {EmissionManager} from 'aave-v3-periphery/contracts/rewards/EmissionManager.sol';

contract AaveV3BatchDeployment is BatchTestProcedures {
address public marketOwner;
Expand Down Expand Up @@ -49,7 +51,8 @@ contract AaveV3BatchDeployment is BatchTestProcedures {
weth9,
address(0),
0.0005e4,
0.0004e4
0.0004e4,
address(0)
);
}

Expand All @@ -61,7 +64,7 @@ contract AaveV3BatchDeployment is BatchTestProcedures {
flags,
deployedContracts
);
checkFullReport(flags, fullReport);
checkFullReport(config, flags, fullReport);

AaveV3TestListing testnetListingPayload = new AaveV3TestListing(
IAaveV3ConfigEngine(fullReport.configEngine),
Expand Down Expand Up @@ -91,7 +94,7 @@ contract AaveV3BatchDeployment is BatchTestProcedures {
deployedContracts
);

checkFullReport(flags, fullReport);
checkFullReport(config, flags, fullReport);

AaveV3TestListing testnetListingPayload = new AaveV3TestListing(
IAaveV3ConfigEngine(fullReport.configEngine),
Expand All @@ -110,6 +113,20 @@ contract AaveV3BatchDeployment is BatchTestProcedures {

function testAaveV3BatchDeploy() public {
checkFullReport(
config,
flags,
deployAaveV3Testnet(marketOwner, roles, config, flags, deployedContracts)
);
}

function testAaveV3Batch_reuseIncentivesProxy() public {
EmissionManager emissionManager = new EmissionManager(poolAdmin);
RewardsController controller = new RewardsController(address(emissionManager));

config.incentivesProxy = address(controller);

checkFullReport(
config,
flags,
deployAaveV3Testnet(marketOwner, roles, config, flags, deployedContracts)
);
Expand Down
5 changes: 3 additions & 2 deletions tests/AaveV3BatchTests.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ contract AaveV3BatchTests is BatchTestProcedures {
address(new WETH9()),
address(0),
0.0005e4,
0.0004e4
0.0004e4,
address(0)
);
flags = DeployFlags(false);

Expand Down Expand Up @@ -111,7 +112,7 @@ contract AaveV3BatchTests is BatchTestProcedures {
deployedContracts
);
vm.stopPrank();
checkFullReport(flags, market);
checkFullReport(config, flags, market);
}

function test0AaveV3SetupDeployment() public {
Expand Down
3 changes: 2 additions & 1 deletion tests/DeploymentsGasLimits.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ contract DeploymentsGasLimits is BatchTestProcedures {
address(new WETH9()),
address(0),
0.0005e4,
0.0004e4
0.0004e4,
address(0)
);
flags = DeployFlags(true);

Expand Down
34 changes: 29 additions & 5 deletions tests/utils/BatchTestProcedures.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {FfiUtils} from '../../src/deployments/contracts/utilities/FfiUtils.sol';
import {DefaultMarketInput} from '../../src/deployments/inputs/DefaultMarketInput.sol';
import {AaveV3BatchOrchestration} from '../../src/deployments/projects/aave-v3-batched/AaveV3BatchOrchestration.sol';
import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol';
import {IRewardsController} from 'aave-v3-periphery/contracts/rewards/interfaces/IRewardsController.sol';
import {ACLManager} from 'aave-v3-core/contracts/protocol/configuration/ACLManager.sol';
import {WETH9} from 'aave-v3-core/contracts/dependencies/weth/WETH9.sol';
import 'aave-v3-periphery/contracts/mocks/testnet-helpers/TestnetERC20.sol';
Expand Down Expand Up @@ -173,7 +174,11 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput
);
}

function checkFullReport(DeployFlags memory flags, MarketReport memory r) internal pure {
function checkFullReport(
MarketConfig memory config,
DeployFlags memory flags,
MarketReport memory r
) internal view {
assertTrue(r.poolAddressesProviderRegistry != address(0), 'r.poolAddressesProviderRegistry');
assertTrue(r.poolAddressesProvider != address(0), 'report.poolAddressesProvider');
assertTrue(r.poolProxy != address(0), 'report.poolProxy');
Expand Down Expand Up @@ -204,12 +209,31 @@ contract BatchTestProcedures is Test, DeployUtils, FfiUtils, DefaultMarketInput
assertTrue(r.aToken != address(0), 'report.aToken');
assertTrue(r.variableDebtToken != address(0), 'report.variableDebtToken');
assertTrue(r.stableDebtToken != address(0), 'report.stableDebtToken');

assertTrue(r.emissionManager != address(0), 'report.emissionManager');
assertTrue(
r.rewardsControllerImplementation != address(0),
'r.rewardsControllerImplementation'
);
assertTrue(r.rewardsControllerProxy != address(0), 'report.rewardsControllerProxy');

if (config.incentivesProxy == address(0)) {
assertTrue(
r.rewardsControllerImplementation != address(0),
'r.rewardsControllerImplementation'
);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the assert inside here are duplicated (could be common for both logic branches), no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, done!

assertEq(
r.emissionManager,
IRewardsController(config.incentivesProxy).getEmissionManager(),
'report.emissionManager should match RewardsController(config.incentivesProxy).getEmissionManager()'
);
assertTrue(
r.rewardsControllerImplementation == address(0),
'r.rewardsControllerImplementation should be empty if incentivesProxy is set'
);
assertEq(
r.rewardsControllerProxy,
config.incentivesProxy,
'r.rewardsControllerProxy should match config input'
);
}
assertTrue(r.configEngine != address(0), 'report.configEngine');
assertTrue(
r.staticATokenFactoryImplementation != address(0),
Expand Down