Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 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
6 changes: 5 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ test = 'tests'
script = 'scripts'
out = 'out'
libs = ['lib']
fs_permissions = [{ access = "read", path = "tests/mocks/JsonBindings.sol" }]
fs_permissions = [
{ access = "read", path = "tests/mocks/JsonBindings.sol" },
{ access = "read", path = "./config" },
{ access = "read-write", path = "./output" }
]
solc_version = "0.8.28"
evm_version = "cancun"
optimizer = true
Expand Down
18 changes: 18 additions & 0 deletions src/deployments/batches/AaveV4AccessBatch.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {BatchReports} from 'src/deployments/types/BatchReports.sol';
import {AaveV4AccessManagerDeployProcedure} from 'src/deployments/procedures/AaveV4AccessManagerDeployProcedure.sol';

contract AaveV4AccessBatch is AaveV4AccessManagerDeployProcedure {
Copy link
Member

Choose a reason for hiding this comment

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

all of these contracts don't need AaveV4 prefix imo, its redundant

Copy link
Contributor Author

Choose a reason for hiding this comment

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

named them using a convention similar to the v3-origin one. But we can decide to use a simpler one instead, no strong opinion.

BatchReports.AccessBatchReport internal _report;

constructor(address admin_) {
address accessManagerAddress = _deployAccessManager(admin_);
_report = BatchReports.AccessBatchReport({accessManagerAddress: accessManagerAddress});
}

function getReport() external view returns (BatchReports.AccessBatchReport memory) {
return _report;
}
}
27 changes: 27 additions & 0 deletions src/deployments/batches/AaveV4GatewaysBatch.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {BatchReports} from 'src/deployments/types/BatchReports.sol';
import {AaveV4NativeTokenGatewayDeployProcedure} from 'src/deployments/procedures/AaveV4NativeTokenGatewayDeployProcedure.sol';
import {AaveV4SignatureGatewayDeployProcedure} from 'src/deployments/procedures/AaveV4SignatureGatewayDeployProcedure.sol';

contract AaveV4GatewaysBatch is
AaveV4NativeTokenGatewayDeployProcedure,
AaveV4SignatureGatewayDeployProcedure
{
BatchReports.GatewaysBatchReport internal _report;

constructor(address nativeWrapper_, address admin_) {
address nativeGatewayAddress = _deployNativeTokenGateway(nativeWrapper_, admin_);
address signatureGatewayAddress = _deploySignatureGateway(admin_);

_report = BatchReports.GatewaysBatchReport({
nativeGatewayAddress: nativeGatewayAddress,
signatureGatewayAddress: signatureGatewayAddress
});
}

function getReport() external view returns (BatchReports.GatewaysBatchReport memory) {
return _report;
}
}
35 changes: 35 additions & 0 deletions src/deployments/batches/AaveV4HubBatch.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {BatchReports} from 'src/deployments/types/BatchReports.sol';
import {AaveV4HubDeployProcedure} from 'src/deployments/procedures/AaveV4HubDeployProcedure.sol';
import {AaveV4InterestRateStrategyDeployProcedure} from 'src/deployments/procedures/AaveV4InterestRateStrategyDeployProcedure.sol';
import {AaveV4TreasurySpokeDeployProcedure} from 'src/deployments/procedures/AaveV4TreasurySpokeDeployProcedure.sol';
import {AaveV4HubConfiguratorDeployProcedure} from 'src/deployments/procedures/AaveV4HubConfiguratorDeployProcedure.sol';

contract AaveV4HubBatch is
AaveV4HubDeployProcedure,
AaveV4InterestRateStrategyDeployProcedure,
AaveV4TreasurySpokeDeployProcedure,
AaveV4HubConfiguratorDeployProcedure
{
BatchReports.HubBatchReport internal _report;

constructor(address admin_, address accessManagerAddress_) {
address hubAddress = _deployHub(accessManagerAddress_);
address irStrategyAddress = _deployInterestRateStrategy(hubAddress);
address treasurySpokeAddress = _deployTreasurySpoke(admin_, hubAddress);
address hubConfiguratorAddress = _deployHubConfigurator(admin_);

_report = BatchReports.HubBatchReport({
hubAddress: hubAddress,
irStrategyAddress: irStrategyAddress,
treasurySpokeAddress: treasurySpokeAddress,
hubConfiguratorAddress: hubConfiguratorAddress
});
}

function getReport() external view returns (BatchReports.HubBatchReport memory) {
return _report;
}
}
60 changes: 60 additions & 0 deletions src/deployments/batches/AaveV4SpokeInstanceBatch.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import 'forge-std/Vm.sol';

import {BatchReports} from 'src/deployments/types/BatchReports.sol';
import {AaveV4SpokeInstanceDeployProcedure} from 'src/deployments/procedures/AaveV4SpokeInstanceDeployProcedure.sol';
import {AaveV4TransparentUpgradeableProxyDeployProcedure} from 'src/deployments/procedures/AaveV4TransparentUpgradeableProxyDeployProcedure.sol';
import {AaveV4AaveOracleDeployProcedure} from 'src/deployments/procedures/AaveV4AaveOracleDeployProcedure.sol';
import {AaveV4SpokeConfiguratorDeployProcedure} from 'src/deployments/procedures/AaveV4SpokeConfiguratorDeployProcedure.sol';

contract AaveV4SpokeInstanceBatch is
AaveV4SpokeInstanceDeployProcedure,
AaveV4TransparentUpgradeableProxyDeployProcedure,
AaveV4AaveOracleDeployProcedure,
AaveV4SpokeConfiguratorDeployProcedure
{
BatchReports.SpokeInstanceBatchReport internal _report;

constructor(
Vm vm,
Copy link
Member

Choose a reason for hiding this comment

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

vm is always constant and can be inherited from a common contract like DeployUtils

Copy link
Member

Choose a reason for hiding this comment

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

all procedures could inherit this common contract with vm and a bool public constant IS_TEST = true to skip on contract size check

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do not plan to make them inherit, but to deploy those to execute the batch, so the idea was to pass the context there directly, but we can change the behavior.

Copy link
Contributor

Choose a reason for hiding this comment

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

skip on contract size check

@DhairyaSethi where were you intending this part would be checked, was there anything else IS_TEST was meant to change in this file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Compiler will check those contract size since they are located in src/.

address deployer,
address admin_,
address accessManagerAddress_,
uint8 oracleDecimals_,
string memory oracleDescription_
) {
address predictedSpokeInstanceAddress = vm.computeCreateAddress(
deployer,
vm.getNonce(deployer) + 2
Copy link
Contributor

Choose a reason for hiding this comment

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

why +2 here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we compute the address for the Spoke proxy, but between the moment we compute and the actual deployment, we have 2 other deployment to be executed (Oracle & Spoke Implementation), which means 2 txs to be broadcasted, and increasing the deployed nonce twice.

Copy link
Contributor

Choose a reason for hiding this comment

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

hm weird I am hitting the SpokeInstance address mismatch error when running this script locally, were you getting the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

when running the script, make sure to use a Foundry account and specify the sender so msg.sender and deployer matches during the whole script, using :
--account ${ACCOUNT} --sender ${SENDER}

Copy link
Contributor

@yan-man yan-man Dec 5, 2025

Choose a reason for hiding this comment

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

hm we cant use vm cheatcodes in actual deployments, so dont think we can use this approach for predicting address

was there a reason you opted not to use create2 for computing predicted address like in v3?

Copy link
Member

Choose a reason for hiding this comment

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

we can, the script which deploys the contracts one by one isn't deployed onchain. only the config part for payload & config engine

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The broadcast logic needs to be reworked to ensure only the actual contracts to deploy would be broadcasted onchain, and not the helper ones.

);

address aaveOracleAddress = _deployAaveOracle(
predictedSpokeInstanceAddress,
oracleDecimals_,
oracleDescription_
);
address spokeImplementationAddress = _deploySpokeInstance(aaveOracleAddress);
address spokeProxyAddress = _deployTransparentUpgradeableProxy(
spokeImplementationAddress,
admin_,
abi.encodeWithSignature('initialize(address)', accessManagerAddress_)
);

require(spokeProxyAddress == predictedSpokeInstanceAddress, 'SpokeInstance address mismatch');

address spokeConfiguratorAddress = _deploySpokeConfigurator(admin_);

_report = BatchReports.SpokeInstanceBatchReport({
aaveOracleAddress: aaveOracleAddress,
spokeImplementationAddress: spokeImplementationAddress,
spokeProxyAddress: spokeProxyAddress,
spokeConfiguratorAddress: spokeConfiguratorAddress
});
}

function getReport() external view returns (BatchReports.SpokeInstanceBatchReport memory) {
return _report;
}
}
16 changes: 16 additions & 0 deletions src/deployments/procedures/AaveV4AaveOracleDeployProcedure.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveOracle} from 'src/spoke/AaveOracle.sol';

contract AaveV4AaveOracleDeployProcedure {
function _deployAaveOracle(
address spoke_,
uint8 decimals_,
string memory description_
) internal returns (address) {
address oracle = address(new AaveOracle(spoke_, decimals_, description_));

return oracle;
}
}
12 changes: 12 additions & 0 deletions src/deployments/procedures/AaveV4AccessManagerDeployProcedure.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AccessManager} from 'src/dependencies/openzeppelin/AccessManager.sol';

contract AaveV4AccessManagerDeployProcedure {
function _deployAccessManager(address admin_) internal returns (address) {
address accessManager = address(new AccessManager(admin_));

return accessManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {HubConfigurator} from 'src/hub/HubConfigurator.sol';

contract AaveV4HubConfiguratorDeployProcedure {
function _deployHubConfigurator(address owner_) internal returns (address) {
address hubConfigurator = address(new HubConfigurator(owner_));

return hubConfigurator;
}
}
12 changes: 12 additions & 0 deletions src/deployments/procedures/AaveV4HubDeployProcedure.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Hub} from 'src/hub/Hub.sol';

contract AaveV4HubDeployProcedure {
function _deployHub(address accessManager_) internal returns (address) {
address hub = address(new Hub(accessManager_));

return hub;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AssetInterestRateStrategy} from 'src/hub/AssetInterestRateStrategy.sol';

contract AaveV4InterestRateStrategyDeployProcedure {
function _deployInterestRateStrategy(address hub_) internal returns (address) {
address interestRateStrategy = address(new AssetInterestRateStrategy(hub_));

return interestRateStrategy;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {NativeTokenGateway} from 'src/position-manager/NativeTokenGateway.sol';

contract AaveV4NativeTokenGatewayDeployProcedure {
function _deployNativeTokenGateway(
address nativeWrapper_,
address owner_
) internal returns (address) {
address nativeTokenGateway = address(new NativeTokenGateway(nativeWrapper_, owner_));

return nativeTokenGateway;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {SignatureGateway} from 'src/position-manager/SignatureGateway.sol';

contract AaveV4SignatureGatewayDeployProcedure {
function _deploySignatureGateway(address owner_) internal returns (address) {
address signatureGateway = address(new SignatureGateway(owner_));

return signatureGateway;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {SpokeConfigurator} from 'src/spoke/SpokeConfigurator.sol';

contract AaveV4SpokeConfiguratorDeployProcedure {
function _deploySpokeConfigurator(address owner_) internal returns (address) {
address spokeConfigurator = address(new SpokeConfigurator(owner_));

return spokeConfigurator;
}
}
12 changes: 12 additions & 0 deletions src/deployments/procedures/AaveV4SpokeInstanceDeployProcedure.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {SpokeInstance} from 'src/spoke/instances/SpokeInstance.sol';

contract AaveV4SpokeInstanceDeployProcedure {
function _deploySpokeInstance(address oracle_) internal returns (address) {
address spokeInstance = address(new SpokeInstance(oracle_));

return spokeInstance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {TransparentUpgradeableProxy} from 'src/dependencies/openzeppelin/TransparentUpgradeableProxy.sol';

contract AaveV4TransparentUpgradeableProxyDeployProcedure {
function _deployTransparentUpgradeableProxy(
address logic_,
address initialOwner_,
bytes memory data_
) internal returns (address) {
address proxy = address(new TransparentUpgradeableProxy(logic_, initialOwner_, data_));

return proxy;
}
}
12 changes: 12 additions & 0 deletions src/deployments/procedures/AaveV4TreasurySpokeDeployProcedure.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {TreasurySpoke} from 'src/spoke/TreasurySpoke.sol';

contract AaveV4TreasurySpokeDeployProcedure {
function _deployTreasurySpoke(address owner_, address hub_) internal returns (address) {
address treasurySpoke = address(new TreasurySpoke(owner_, hub_));

return treasurySpoke;
}
}
27 changes: 27 additions & 0 deletions src/deployments/types/BatchReports.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library BatchReports {
struct AccessBatchReport {
address accessManagerAddress;
}

struct SpokeInstanceBatchReport {
address spokeImplementationAddress;
address spokeProxyAddress;
address aaveOracleAddress;
address spokeConfiguratorAddress;
}

struct HubBatchReport {
address hubAddress;
address irStrategyAddress;
address treasurySpokeAddress;
address hubConfiguratorAddress;
}

struct GatewaysBatchReport {
address signatureGatewayAddress;
address nativeGatewayAddress;
}
}
11 changes: 11 additions & 0 deletions src/deployments/utils/DeployUtils.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import 'forge-std/StdJson.sol';
import 'forge-std/Vm.sol';

contract DeployUtils {
using stdJson for string;

Vm private constant vm = Vm(address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))));
}
Loading
Loading