Skip to content

Commit

Permalink
Add config.incentivesProxy to reuse RewardsController proxy across in…
Browse files Browse the repository at this point in the history
…stances in same EVM network (aave-dao#48)

* feat: add config.incentivesProxy to reuse RewardsController proxy across instances in same EVM network

* chore: run lint:fix

* chore: move duplicated check outside if statement at BatchTestProcedures

* chore: run lint:fix

---------

Co-authored-by: kartojal <david@catapulta.sh>
  • Loading branch information
kartojal and kartojal committed Aug 21, 2024
1 parent 97356e3 commit f444b34
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 44 deletions.
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 {
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

0 comments on commit f444b34

Please sign in to comment.