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
5 changes: 3 additions & 2 deletions src/deployments/batches/AaveV4TreasurySpokeBatch.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ contract AaveV4TreasurySpokeBatch is AaveV4TreasurySpokeDeployProcedure {
/// @dev Constructor.
/// @param owner_ The owner of the TreasurySpoke proxy admin and initializer.
/// @param salt_ The CREATE2 salt for deterministic deployment.
constructor(address owner_, bytes32 salt_) {
address treasurySpoke = _deployTreasurySpoke({owner: owner_, salt: salt_});
/// @param hub_ The hub connected with Treasury Spoke.
constructor(address owner_, bytes32 salt_, address hub_) {
address treasurySpoke = _deployTreasurySpoke({owner: owner_, salt: salt_, hub: hub_});
_report = BatchReports.TreasurySpokeBatchReport({treasurySpoke: treasurySpoke});
}

Expand Down
7 changes: 5 additions & 2 deletions src/deployments/orchestration/AaveV4DeployBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,17 @@ library AaveV4DeployBase {
/// @notice Deploys the Treasury Spoke batch containing the TreasurySpoke proxy.
/// @param owner The owner of the TreasurySpoke.
/// @param salt The CREATE2 salt for deterministic deployment.
/// @param hub The hub connected with Treasury Spoke.
/// @return The Treasury Spoke batch report.
function deployTreasurySpokeBatch(
address owner,
bytes32 salt
bytes32 salt,
address hub
) internal returns (BatchReports.TreasurySpokeBatchReport memory) {
AaveV4TreasurySpokeBatch treasurySpokeBatch = new AaveV4TreasurySpokeBatch({
owner_: owner,
salt_: salt
salt_: salt,
hub_: hub
});
return treasurySpokeBatch.getReport();
}
Expand Down
9 changes: 6 additions & 3 deletions src/deployments/orchestration/AaveV4DeployOrchestration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ library AaveV4DeployOrchestration {
) internal returns (OrchestrationReports.FullDeploymentReport memory report) {
bytes32 salt = _deriveSalt({deployer: deployer, salt: deployInputs.salt});
report.salt = deployInputs.salt;
address hub;

// Deploy Access Batch
// initialize with deployer as access manager admin
Expand Down Expand Up @@ -67,7 +68,8 @@ library AaveV4DeployOrchestration {
report.treasurySpokeBatchReport = _deployTreasurySpokeBatch({
logger: logger,
treasurySpokeOwner: deployInputs.treasurySpokeOwner,
salt: salt
salt: salt,
hub: hub
});

// Validate label uniqueness (duplicate labels produce identical CREATE2 salts)
Expand Down Expand Up @@ -331,10 +333,11 @@ library AaveV4DeployOrchestration {
function _deployTreasurySpokeBatch(
Logger logger,
address treasurySpokeOwner,
bytes32 salt
bytes32 salt,
address hub
) internal returns (BatchReports.TreasurySpokeBatchReport memory report) {
logger.logHeader1('deploying TreasurySpokeBatch');
report = AaveV4DeployBase.deployTreasurySpokeBatch({owner: treasurySpokeOwner, salt: salt});
report = AaveV4DeployBase.deployTreasurySpokeBatch({owner: treasurySpokeOwner, salt: salt, hub: hub});
logger.log('TreasurySpoke', report.treasurySpoke);
logger.logNewLine();
return report;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,22 @@ contract AaveV4TreasurySpokeDeployProcedure is AaveV4DeployProcedureBase {
/// @notice Deploys a Treasury Spoke instance via CREATE2 and sets up a transparent proxy.
/// @param owner The owner of the proxy admin and the TreasurySpoke initializer.
/// @param salt The CREATE2 salt for deterministic deployment.
/// @return The address of the deployed transparent proxy contract.
function _deployTreasurySpoke(address owner, bytes32 salt) internal returns (address) {
/// @param hub The hub connected with Treasury Spoke, encoded to prevent the CREATE2 deployment from failing.
/// @return The address of the deployed transparent proxy contract
function _deployTreasurySpoke(address owner, bytes32 salt, address hub) internal returns (address) {
require(owner != address(0), 'invalid owner');

bytes memory bytecode = abi.encodePacked(
type(TreasurySpokeInstance).creationCode,
/* The hub must be encoded because it is an argument in the TreasurySpoke constructor,
constructor arguments can alter the final bytecode causing the
CREATE2 deterministic deployement to fail, so encoding ensures the deploy succeds */
abi.encode(hub)
);

address implementation = Create2Utils.create2Deploy(
salt,
type(TreasurySpokeInstance).creationCode
bytecode
);
return
Create2Utils.proxify(
Expand Down
7 changes: 7 additions & 0 deletions src/spoke/TreasurySpoke.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,15 @@ import {ITreasurySpoke} from 'src/spoke/interfaces/ITreasurySpoke.sol';
/// @dev Dedicated to a single user, controlled exclusively by the owner.
/// @dev Allows withdraw to claim fees and supply to invest back into any Hub asset.
abstract contract TreasurySpoke is ITreasurySpoke, Ownable2StepUpgradeable {
/// @notice The hub of treasury spoke, each treasury spoke must be connected with a hub
address public immutable HUB;

using SafeERC20 for IERC20;

constructor(address _hub) {
HUB = _hub;
}

/// @dev To be overridden by the inheriting TreasurySpoke instance contract.
function initialize(address owner) external virtual;

Expand Down
2 changes: 1 addition & 1 deletion src/spoke/instances/TreasurySpokeInstance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ contract TreasurySpokeInstance is TreasurySpoke {
uint64 public constant SPOKE_REVISION = 1;

/// @dev Constructor.
constructor() {
constructor(address _hub) TreasurySpoke(_hub) {
_disableInitializers();
}

Expand Down
2 changes: 2 additions & 0 deletions tests/config-engine/BaseConfigEngine.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ abstract contract BaseConfigEngineTest is Test, Create2TestHelper {
address internal ACCOUNT = makeAddr('ACCOUNT');
address internal TARGET = makeAddr('TARGET');
address internal USER = makeAddr('USER');
address internal TREASURY_SPOKE_HUB;
address internal PAYLOADS_CONTROLLER = makeAddr('PAYLOADS_CONTROLLER');
address internal PROXY_ADMIN_OWNER = makeAddr('PROXY_ADMIN_OWNER');

Expand Down Expand Up @@ -133,6 +134,7 @@ abstract contract BaseConfigEngineTest is Test, Create2TestHelper {
TestTypes.TestEnvReport memory report = AaveV4TestOrchestration.deployTestEnv({
admin: ADMIN,
treasuryAdmin: ADMIN,
hub: TREASURY_SPOKE_HUB,
hubCount: NUM_HUBS,
spokeCount: NUM_SPOKES,
nativeWrapper: address(weth),
Expand Down
6 changes: 4 additions & 2 deletions tests/contracts/hub/configurator/HubConfigurator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,8 @@ contract HubConfiguratorTest is Base {
// Change the fee receiver
address newTreasurySpoke = AaveV4TestOrchestration.deployTestTreasurySpoke({
owner: HUB_ADMIN,
salt: bytes32('newTreasurySpoke1')
salt: bytes32('newTreasurySpoke1'),
hub: TreasurySpokeHub
});
vm.prank(HUB_CONFIGURATOR_ADMIN);
hubConfigurator.updateFeeReceiver(address(hub1), daiAssetId, newTreasurySpoke);
Expand Down Expand Up @@ -403,7 +404,8 @@ contract HubConfiguratorTest is Base {
// Change the fee receiver
address newTreasurySpoke = AaveV4TestOrchestration.deployTestTreasurySpoke({
owner: HUB_ADMIN,
salt: bytes32('newTreasurySpoke2')
salt: bytes32('newTreasurySpoke2'),
hub: TreasurySpokeHub
});
vm.prank(HUB_CONFIGURATOR_ADMIN);
hubConfigurator.updateFeeReceiver(address(hub1), daiAssetId, newTreasurySpoke);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ contract SpokeMultipleHubBase is Base {
TestTypes.TestEnvReport memory report = AaveV4TestOrchestration.deployTestEnv({
admin: ADMIN,
treasuryAdmin: ADMIN,
hub: TreasurySpokeHub,
hubCount: 2,
spokeCount: 2,
nativeWrapper: makeAddr('nativeWrapper'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ contract TreasurySpokeUpgradeableTest is Base {
}

function test_proxy_constructor_revertsWith_InvalidAddress() public {
TreasurySpokeInstance impl = new TreasurySpokeInstance();
TreasurySpokeInstance impl = new TreasurySpokeInstance(TreasurySpokeHub);
vm.expectRevert(
abi.encodeWithSelector(OwnableUpgradeable.OwnableInvalidOwner.selector, address(0))
);
Expand All @@ -139,7 +139,7 @@ contract TreasurySpokeUpgradeableTest is Base {
}

function test_proxy_reinitialization_revertsWith_CallerNotProxyAdmin() public {
TreasurySpokeInstance impl = new TreasurySpokeInstance();
TreasurySpokeInstance impl = new TreasurySpokeInstance(TreasurySpokeHub);
ITransparentUpgradeableProxy proxy = ITransparentUpgradeableProxy(
AaveV4TestOrchestration.proxify(
address(impl),
Expand All @@ -148,7 +148,7 @@ contract TreasurySpokeUpgradeableTest is Base {
)
);

TreasurySpokeInstance impl2 = new TreasurySpokeInstance();
TreasurySpokeInstance impl2 = new TreasurySpokeInstance(TreasurySpokeHub);
vm.expectRevert();
vm.prank(_makeUser());
proxy.upgradeToAndCall(
Expand All @@ -160,6 +160,6 @@ contract TreasurySpokeUpgradeableTest is Base {
function _deployMockTreasurySpokeInstance(
uint64 revision
) internal returns (MockTreasurySpokeInstance) {
return new MockTreasurySpokeInstance(revision);
return new MockTreasurySpokeInstance(revision, TreasurySpokeHub);
}
}
2 changes: 1 addition & 1 deletion tests/contracts/treasury-spoke/TreasurySpoke.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ contract TreasurySpokeTest is Base {
}

function test_deploy_reverts_on_invalid_params() public {
TreasurySpokeInstance impl = new TreasurySpokeInstance();
TreasurySpokeInstance impl = new TreasurySpokeInstance(TreasurySpokeHub);
vm.expectRevert(
abi.encodeWithSelector(OwnableUpgradeable.OwnableInvalidOwner.selector, address(0))
);
Expand Down
7 changes: 4 additions & 3 deletions tests/deployments/batches/AaveV4TreasurySpokeBatch.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ contract AaveV4TreasurySpokeBatchTest is BatchBaseTest {

function setUp() public override {
super.setUp();
treasurySpokeBatch = new AaveV4TreasurySpokeBatch({owner_: admin, salt_: salt});
treasurySpokeBatch = new AaveV4TreasurySpokeBatch({owner_: admin, salt_: salt, hub_: TreasurySpokeHub});
report = treasurySpokeBatch.getReport();
}

Expand All @@ -27,13 +27,14 @@ contract AaveV4TreasurySpokeBatchTest is BatchBaseTest {

function test_revert_zeroOwner() public {
vm.expectRevert('invalid owner');
new AaveV4TreasurySpokeBatch({owner_: address(0), salt_: keccak256('zeroOwnerSalt')});
new AaveV4TreasurySpokeBatch({owner_: address(0), salt_: keccak256('zeroOwnerSalt'), hub_: address(0)});
}

function test_differentSaltProducesDifferentAddress() public {
AaveV4TreasurySpokeBatch newBatch = new AaveV4TreasurySpokeBatch({
owner_: admin,
salt_: keccak256('differentSalt')
salt_: keccak256('differentSalt'),
hub_: TreasurySpokeHub
});
assertNotEq(report.treasurySpoke, newBatch.getReport().treasurySpoke);
}
Expand Down
1 change: 1 addition & 0 deletions tests/deployments/batches/BatchBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ contract BatchBaseTest is Create2TestHelper {
address public admin = makeAddr('admin');
address public feeReceiver = makeAddr('feeReceiver');
bytes32 public salt;
address public TreasurySpokeHub;
address public accessManager;
address public nativeWrapper;
bytes internal hubBytecode;
Expand Down
11 changes: 7 additions & 4 deletions tests/deployments/orchestration/AaveV4TestOrchestration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ library AaveV4TestOrchestration {
address nativeWrapper,
bytes memory hubBytecode,
bytes memory spokeBytecode,
bytes32 salt
bytes32 salt,
address hub
) external returns (TestTypes.TestEnvReport memory) {
TestTypes.TestEnvReport memory report;

Expand All @@ -77,7 +78,8 @@ library AaveV4TestOrchestration {
report.treasurySpoke = AaveV4DeployBase
.deployTreasurySpokeBatch({
owner: treasuryAdmin,
salt: keccak256(abi.encodePacked(salt, 'treasurySpoke'))
salt: keccak256(abi.encodePacked(salt, 'treasurySpoke')),
hub: hub
})
.treasurySpoke;

Expand Down Expand Up @@ -197,9 +199,10 @@ library AaveV4TestOrchestration {

function deployTestTreasurySpoke(
address owner,
bytes32 salt
bytes32 salt,
address hub
) external returns (address treasurySpoke) {
return AaveV4DeployBase.deployTreasurySpokeBatch({owner: owner, salt: salt}).treasurySpoke;
return AaveV4DeployBase.deployTreasurySpokeBatch({owner: owner, salt: salt, hub: hub}).treasurySpoke;
}

function configureHubsSpokes(ConfigData.AddSpokeParams[] memory paramsList) external {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ contract AaveV4TreasurySpokeDeployProcedureTest is ProceduresBase {
function test_deployTreasurySpoke() public {
address treasurySpoke = aaveV4TreasurySpokeDeployProcedureWrapper.deployTreasurySpoke(
owner,
salt
salt,
hub
);
assertEq(Ownable(treasurySpoke).owner(), owner);
assertEq(Ownable(ProxyHelper.getProxyAdmin(treasurySpoke)).owner(), owner);
}

function test_deployTreasurySpoke_reverts() public {
vm.expectRevert('invalid owner');
aaveV4TreasurySpokeDeployProcedureWrapper.deployTreasurySpoke({owner: address(0), salt: salt});
aaveV4TreasurySpokeDeployProcedureWrapper.deployTreasurySpoke({owner: address(0), salt: salt, hub: hub});
}
}
2 changes: 1 addition & 1 deletion tests/helpers/mocks/MockTreasurySpokeInstance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ contract MockTreasurySpokeInstance is TreasurySpoke {
* @dev It sets the spoke revision and disables the initializers.
* @param spokeRevision_ The revision of the spoke contract.
*/
constructor(uint64 spokeRevision_) {
constructor(uint64 spokeRevision_, address _hub) TreasurySpoke(_hub) {
SPOKE_REVISION = spokeRevision_;
_disableInitializers();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {AaveV4TreasurySpokeDeployProcedure} from 'src/deployments/procedures/dep
contract AaveV4TreasurySpokeDeployProcedureWrapper is AaveV4TreasurySpokeDeployProcedure {
bool public IS_TEST = true;

function deployTreasurySpoke(address owner, bytes32 salt) external returns (address) {
return _deployTreasurySpoke(owner, salt);
function deployTreasurySpoke(address owner, bytes32 salt, address hub) external returns (address) {
return _deployTreasurySpoke(owner, salt, hub);
}
}
1 change: 1 addition & 0 deletions tests/setup/Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ abstract contract Base is BaseHelpers, BatchTestProcedures {
report = AaveV4TestOrchestration.deployTestEnv({
admin: ADMIN,
treasuryAdmin: TREASURY_ADMIN,
hub: TreasurySpokeHub,
hubCount: numHubs,
spokeCount: numSpokes,
nativeWrapper: address(tokenList.weth),
Expand Down
1 change: 1 addition & 0 deletions tests/utils/BatchTestProcedures.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ contract BatchTestProcedures is Test, Create2TestHelper, WETHDeployProcedure {
bytes4[] internal _hubFeeMinterRoleSelectors;
bytes4[] internal _hubConfiguratorRoleSelectors;
address internal _deployer = makeAddr('deployer');
address internal TreasurySpokeHub;
// Skip native wrapper check when nativeWrapper address is not available (e.g. post-deployment JSON report)
bool internal _skipNativeWrapperCheck;

Expand Down