-
Notifications
You must be signed in to change notification settings - Fork 102
feat : deploy helpers for external usage #1212
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
base: main
Are you sure you want to change the base?
Changes from 8 commits
d20a3a5
bec36f3
bfba762
0590200
69684cd
b2b6313
3e1596c
7f96097
8789f61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| // SPDX-License-Identifier: UNLICENSED | ||
| // Copyright (c) 2025 Aave Labs | ||
| pragma solidity ^0.8.0; | ||
|
|
||
| import {Script} from 'forge-std/Script.sol'; | ||
|
|
||
| contract GenerateHubBytecodeScript is Script { | ||
| string private constant HUB_BYTECODE_PATH = 'tests/bin/hub.bytecode'; | ||
| string private constant SPOKE_INSTANCE_BYTECODE_PATH = 'tests/bin/spokeInstance.bytecode'; | ||
|
|
||
| function run() external { | ||
| bytes memory hubBytecode = vm.getCode('src/hub/Hub.sol:Hub'); | ||
| vm.writeFileBinary(HUB_BYTECODE_PATH, hubBytecode); | ||
|
|
||
| string memory artifact = vm.readFile('out/SpokeInstance.sol/SpokeInstance.json'); | ||
| string memory spokeHex = vm.parseJsonString(artifact, '.bytecode.object'); | ||
|
Kogaroshi marked this conversation as resolved.
|
||
| vm.writeFile(SPOKE_INSTANCE_BYTECODE_PATH, spokeHex); | ||
|
Kogaroshi marked this conversation as resolved.
|
||
| } | ||
|
Kogaroshi marked this conversation as resolved.
|
||
| } | ||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| // SPDX-License-Identifier: UNLICENSED | ||
| // Copyright (c) 2025 Aave Labs | ||
| pragma solidity ^0.8.0; | ||
|
|
||
| import {Test} from 'forge-std/Test.sol'; | ||
|
|
||
| import {BytecodeLoader} from 'tests/utils/BytecodeLoader.sol'; | ||
|
|
||
| contract GenerateBytecodeScript is Test { | ||
|
Kogaroshi marked this conversation as resolved.
|
||
| string private constant HUB_BYTECODE_PATH = 'tests/bin/hub.bytecode'; | ||
| string private constant SPOKE_INSTANCE_BYTECODE_PATH = 'tests/bin/spokeInstance.bytecode'; | ||
|
Kogaroshi marked this conversation as resolved.
|
||
|
|
||
| function test_generated_HubBytecode() public view { | ||
| bytes memory hubBytecode = vm.getCode('src/hub/Hub.sol:Hub'); | ||
|
|
||
| assertEq( | ||
| hubBytecode, | ||
| BytecodeLoader.loadHubBytecode(), | ||
| 'Loaded Hub bytecode does not match generated bytecode' | ||
| ); | ||
| } | ||
|
|
||
| function test_generated_SpokeInstanceBytecode() public view { | ||
| bytes memory spokeInstanceBytecode = vm.getCode( | ||
| 'src/spoke/instances/SpokeInstance.sol:SpokeInstance' | ||
| ); | ||
|
|
||
| assertEq( | ||
| spokeInstanceBytecode, | ||
| BytecodeLoader.loadSpokeInstanceBytecode(), | ||
| 'Loaded SpokeInstance bytecode does not match generated bytecode' | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| // SPDX-License-Identifier: UNLICENSED | ||
| // Copyright (c) 2025 Aave Labs | ||
| pragma solidity ^0.8.0; | ||
|
|
||
| import {Vm} from 'forge-std/Vm.sol'; | ||
|
|
||
| import {LiquidationLogic} from 'src/spoke/libraries/LiquidationLogic.sol'; | ||
|
|
||
| library BytecodeLoader { | ||
| Vm private constant vm = Vm(address(bytes20(uint160(uint256(keccak256('hevm cheat code')))))); | ||
|
|
||
| string private constant HUB_BYTECODE_PATH = 'tests/bin/hub.bytecode'; | ||
| string private constant SPOKE_INSTANCE_BYTECODE_PATH = 'tests/bin/spokeInstance.bytecode'; | ||
|
|
||
|
Kogaroshi marked this conversation as resolved.
|
||
| string private constant LIQUIDATION_LOGIC_PLACEHOLDER = | ||
| '__$a48140799943db40fec4e369e92a011fa5$__'; | ||
|
Kogaroshi marked this conversation as resolved.
|
||
|
|
||
| function loadHubBytecode() public view returns (bytes memory) { | ||
| return vm.readFileBinary(HUB_BYTECODE_PATH); | ||
| } | ||
|
|
||
| function loadSpokeInstanceBytecode() public view returns (bytes memory) { | ||
| string memory hexBytecode = vm.readFile(SPOKE_INSTANCE_BYTECODE_PATH); | ||
| string memory addrHex = vm.replace( | ||
| vm.toString(abi.encodePacked(address(LiquidationLogic))), | ||
| '0x', | ||
| '' | ||
| ); | ||
| string memory linked = vm.replace(hexBytecode, LIQUIDATION_LOGIC_PLACEHOLDER, addrHex); | ||
| return vm.parseBytes(linked); | ||
| } | ||
|
Kogaroshi marked this conversation as resolved.
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // SPDX-License-Identifier: UNLICENSED | ||
| // Copyright (c) 2025 Aave Labs | ||
| pragma solidity ^0.8.0; | ||
|
|
||
| import {BytecodeLoader} from 'tests/utils/BytecodeLoader.sol'; | ||
|
|
||
| import {Create2Utils} from 'tests/Create2Utils.sol'; | ||
|
|
||
| /// @notice Helper to deploy Hub from custom profile precompiled bytecode | ||
| contract DeployHub { | ||
| /// @notice Deploys a Hub contract using CREATE2 and the stored bytecode with the provided deployment arguments. | ||
| /// @param deployArgs The constructor arguments for the Hub contract, encoded as bytes. | ||
| /// @param salt The salt to use for the CREATE2 deployment, allowing for deterministic address generation. | ||
| /// @return The address of the deployed Hub contract. | ||
| function deployHub(bytes memory deployArgs, bytes32 salt) public returns (address) { | ||
| Create2Utils.loadCreate2Factory(); | ||
|
|
||
| bytes memory bytecode = BytecodeLoader.loadHubBytecode(); | ||
|
|
||
| return Create2Utils.create2Deploy(salt, abi.encodePacked(bytecode, deployArgs)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| // SPDX-License-Identifier: UNLICENSED | ||
| // Copyright (c) 2025 Aave Labs | ||
| pragma solidity ^0.8.0; | ||
|
|
||
| import {BytecodeLoader} from 'tests/utils/BytecodeLoader.sol'; | ||
|
|
||
| import {Create2Utils} from 'tests/Create2Utils.sol'; | ||
| import {DeployUtils} from 'tests/DeployUtils.sol'; | ||
|
|
||
| /// @notice Helper to deploy Spoke from custom profile precompiled bytecode | ||
| contract DeploySpoke { | ||
| /// @notice Deploys a proxified SpokeInstance contract using CREATE2 and the stored bytecode with the provided deployment arguments, and proxified using initialize arguments. | ||
| /// @param deployArgs The constructor arguments for the SpokeInstance implementation contract, encoded as bytes. | ||
| /// @param initArgs The initialization arguments for the TransparentUpgradeableProxy, encoded as bytes. | ||
| /// @param salt The salt to use for the CREATE2 deployment, allowing for deterministic address generation. | ||
| /// @return The address of the deployed SpokeInstance implementation | ||
| /// @return The address of the deployed SpokeInstance proxy | ||
| function deploySpoke( | ||
| bytes memory deployArgs, | ||
| bytes memory initArgs, | ||
| bytes32 salt | ||
| ) public returns (address, address) { | ||
| Create2Utils.loadCreate2Factory(); | ||
|
|
||
| bytes memory bytecode = BytecodeLoader.loadSpokeInstanceBytecode(); | ||
|
|
||
| address impl = Create2Utils.create2Deploy(salt, abi.encodePacked(bytecode, deployArgs)); | ||
| address proxy = DeployUtils.proxify(impl, msg.sender, initArgs); | ||
|
||
|
|
||
| return (impl, proxy); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.