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

consistent registry addresses #1146

Merged
merged 5 commits into from
Aug 28, 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
56 changes: 56 additions & 0 deletions contracts/src/factory/HyperdriveCreate2Factory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.22;

import { Create2 } from "openzeppelin/utils/Create2.sol";

/// @author DELV
/// @title HyperdriveCreate2Factory
/// @notice Uses Create2 to deploy a contract to a precomputable address that
/// is only dependent on the contract's bytecode and the provided salt.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
contract HyperdriveCreate2Factory {
/// @notice Deploy the contract with the provided creation code to a
/// precomputable address determined by only the salt and bytecode.
/// @param _salt Salt to use for the deployment.
/// @param _creationCode Creation code of the contract to deploy.
/// @return deployed Address of the deployed contract.
function deploy(
bytes32 _salt,
bytes memory _creationCode
) external payable returns (address deployed) {
return Create2.deploy(msg.value, _salt, _creationCode);
}

/// @notice Deploy the contract with the provided creation code to a
/// precomputable address determined by only the deployer address
/// and salt.
/// @param _salt Salt to use for the deployment.
/// @param _creationCode Creation code of the contract to deploy.
/// @param _initializationCode Encoded function data to be called on the
/// newly deployed contract.
/// @return deployed Address of the deployed contract.
function deploy(
bytes32 _salt,
bytes memory _creationCode,
bytes memory _initializationCode
) external payable returns (address deployed) {
deployed = Create2.deploy(msg.value, _salt, _creationCode);
(bool success, ) = deployed.call(_initializationCode);
require(success, "FAILED_INITIALIZATION");
return deployed;
}

/// @notice Use the deployer address and salt to compute the address of a
/// contract deployed via Create2.
/// @param _salt Salt of the deployed contract.
/// @param _bytecodeHash Hash of the contract bytecode.
/// @return Address of the Create2 deployed contract.
function getDeployed(
bytes32 _salt,
bytes32 _bytecodeHash
) external view returns (address) {
return Create2.computeAddress(_salt, _bytecodeHash);
}
}
3 changes: 1 addition & 2 deletions deployments.json
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,5 @@
"address": "0xA29A771683b4857bBd16e1e4f27D5B6bfF53209B",
"timestamp": "2024-08-14T19:30:51.584Z"
}

}
}
}
84 changes: 78 additions & 6 deletions tasks/deploy/registry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { subtask } from "hardhat/config";
import {
Address,
encodeAbiParameters,
encodeFunctionData,
encodePacked,
keccak256,
stringToHex,
} from "viem";
import {
HyperdriveDeployBaseTask,
HyperdriveDeployNamedTaskParams,
Expand All @@ -12,15 +20,79 @@ HyperdriveDeployBaseTask(
"deploys the hyperdrive registry to the configured chain",
),
).setAction(
async ({ name, ...rest }: DeployRegistryParams, { hyperdriveDeploy }) => {
async (
{ name }: DeployRegistryParams,
{ hyperdriveDeploy, artifacts, getNamedAccounts, viem },
) => {
console.log("\nRunning deploy:registry ...");
await hyperdriveDeploy.ensureDeployed(
// Skip if the registry is already deployed.
if (!!hyperdriveDeploy.deployments.byNameSafe(name)) {
console.log(`skipping ${name}, found existing deployment`);
return;
}

// Ensure the Create2 factory is deployed.
let create2Deployer = await hyperdriveDeploy.ensureDeployed(
"Hyperdrive Create2 Factory",
"HyperdriveCreate2Factory",
[],
);

// Take the `REGISTRY_SALT` string and convert it to bytes32
// compatible formatting.
let salt = stringToHex(process.env.REGISTRY_SALT! as `0x${string}`, {
size: 32,
});

// Assemble the creation code by packing the registry contract's
// bytecode with its constructor arguments.
let deployer = (await getNamedAccounts())["deployer"] as Address;
let artifact = artifacts.readArtifactSync("HyperdriveRegistry");
let creationCode = encodePacked(
["bytes", "bytes"],
[
artifact.bytecode,
encodeAbiParameters(
[{ name: "_name", type: "string" }],
[name],
),
],
);
let initializationData = encodeFunctionData({
abi: artifact.abi,
functionName: "updateAdmin",
args: [deployer],
});

// Call the Create2 deployer to deploy the contract.
let tx = await create2Deployer.write.deploy([
salt,
creationCode,
initializationData,
]);
let pc = await viem.getPublicClient();
await pc.waitForTransactionReceipt({ hash: tx });

// Use the deployer address to back-compute the deployed contract address
// and store the deployment configuration in deployments.json.
console.log(` - saving ${name}...`);
let deployedAddress = await create2Deployer.read.getDeployed([
salt,
keccak256(creationCode),
]);
hyperdriveDeploy.deployments.add(
name,
"HyperdriveRegistry",
[name],
{
...rest,
},
deployedAddress,
);

// Print out the current number of instances in the registry.
let registry = await viem.getContractAt(
"HyperdriveRegistry",
deployedAddress,
);
console.log(
`NumFactories: ${await registry.read.getNumberOfInstances()}`,
);
},
);
7 changes: 6 additions & 1 deletion tasks/registry/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ HyperdriveDeployNamedTask(
"DELV Hyperdrive Registry",
).address as `0x${string}`;
const registryContract = await viem.getContractAt(
"IHyperdriveGovernedRegistry",
"HyperdriveRegistry",
registryAddress,
);
let tx = await registryContract.write.setInstanceInfo([
Expand All @@ -49,5 +49,10 @@ HyperdriveDeployNamedTask(
]);
let pc = await viem.getPublicClient();
await pc.waitForTransactionReceipt({ hash: tx });
let instanceCount =
await registryContract.read.getNumberOfInstances();
console.log(
`there are now ${instanceCount} instances in the registry`,
);
},
);
Loading
Loading