Skip to content

Commit

Permalink
fix stack too deep error for coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
oveddan committed Sep 28, 2023
1 parent f1208f4 commit c2ce689
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 60 deletions.
93 changes: 55 additions & 38 deletions src/deployment/DeterministicDeployerScript.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,62 +99,79 @@ contract DeterministicDeployerScript is Script {
signature = signatures.readBytes(string.concat(".", string.concat(vm.toString(chain))));
}

function getDeterministicDeploymentParams(
address deployerAddress,
bytes memory proxyCreationCode,
uint256 proxyShimSaltSuffix
) internal returns (DeterministicParams memory) {
// 1. Get salt with first bytes that match address, and resulting determinisitic factory proxy deployer address
function getProxyDeployerParams() internal returns (bytes32 proxyDeployerSalt, bytes memory proxyDeployerCreationCode, address proxyDeployerAddress) {
proxyDeployerSalt = ZoraDeployerUtils.FACTORY_DEPLOYER_DEPLOYMENT_SALT;

// replace first 20 characters of salt with deployer address, so that the salt can be used with
// ImmutableCreate2Factory.safeCreate2 when called by this deployer's account:
bytes32 proxyDeployerSalt = ZoraDeployerUtils.FACTORY_DEPLOYER_DEPLOYMENT_SALT;

bytes memory proxyDeployerCreationCode = type(DeterministicProxyDeployer).creationCode;
proxyDeployerCreationCode = type(DeterministicProxyDeployer).creationCode;

// we can know deterministically what the address of the new factory proxy deployer will be, given it's deployed from with the salt and init code,
// from the ImmutableCreate2Factory
address proxyDeployerAddress = ZoraDeployerUtils.IMMUTABLE_CREATE2_FACTORY.findCreate2Address(proxyDeployerSalt, proxyDeployerCreationCode);

console2.log("expected factory deployer address:", proxyDeployerAddress);

// 2. Get random proxy shim salt, and resulting deterministic address
proxyDeployerAddress = ZoraDeployerUtils.IMMUTABLE_CREATE2_FACTORY.findCreate2Address(proxyDeployerSalt, proxyDeployerCreationCode);
}

// Proxy shim will be initialized with the factory deployer address as the owner, allowing only the factory deployer to upgrade the proxy,
// to the eventual factory implementation
bytes memory proxyShimInitCode = abi.encodePacked(type(ProxyShim).creationCode, abi.encode(proxyDeployerAddress));
function getProxyShimParams(
address proxyDeployerAddress,
address deployerAddress,
uint256 proxyShimSaltSuffix
) internal returns (bytes memory proxyShimInitCode, bytes32 proxyShimSalt, address proxyShimAddress) {
proxyShimInitCode = abi.encodePacked(type(ProxyShim).creationCode, abi.encode(proxyDeployerAddress));

// create any arbitrary salt for proxy shim (this can be anything, we just care about the resulting address)
bytes32 proxyShimSalt = saltWithAddressInFirst20Bytes(deployerAddress, proxyShimSaltSuffix);
proxyShimSalt = saltWithAddressInFirst20Bytes(deployerAddress, proxyShimSaltSuffix);

// now get deterministic proxy shim address based on salt, deployer address, which will be DeterministicProxyDeployer address and init code
address proxyShimAddress = Create2.computeAddress(proxyShimSalt, keccak256(proxyShimInitCode), proxyDeployerAddress);

console2.log("proxy shim address:");
console2.log(proxyShimAddress);

// 3. Mine for a salt that can be used to deterministically create the factory proxy, given the proxy shim address, which is passed as the
// constructor argument, and the deployer, which is the new factory proxy deployer, which we know the address of deterministically
proxyShimAddress = Create2.computeAddress(proxyShimSalt, keccak256(proxyShimInitCode), proxyDeployerAddress);
}

function getProxyParams(
bytes memory proxyCreationCode,
address proxyShimAddress,
address proxyDeployerAddress
) internal returns (bytes32 proxySalt, address deterministicProxyAddress) {
bytes memory factoryProxyInitCode = abi.encodePacked(proxyCreationCode, abi.encode(proxyShimAddress, ""));
bytes32 creationCodeHash = keccak256(factoryProxyInitCode);

console.log("init code hash: ", LibString.toHexStringNoPrefix(uint256(creationCodeHash), 32));
(proxySalt, deterministicProxyAddress) = mineSalt(proxyDeployerAddress, creationCodeHash, "777777");
}

(bytes32 proxySalt, address deterministicProxyAddress) = mineSalt(proxyDeployerAddress, creationCodeHash, "777777");
function getDeterministicDeploymentParams(
address deployerAddress,
bytes memory proxyCreationCode,
uint256 proxyShimSaltSuffix
) internal returns (DeterministicParams memory) {
// 1. Get salt with first bytes that match address, and resulting determinisitic factory proxy deployer address
(bytes32 proxyDeployerSalt, bytes memory proxyDeployerCreationCode, address proxyDeployerAddress) = getProxyDeployerParams();
// replace first 20 characters of salt with deployer address, so that the salt can be used with
// ImmutableCreate2Factory.safeCreate2 when called by this deployer's account:

DeterministicParams memory result = DeterministicParams({
proxyDeployerCreationCode: proxyDeployerCreationCode,
proxyCreationCode: proxyCreationCode,
deployerAddress: deployerAddress,
// 2. Get random proxy shim salt, and resulting deterministic address
// Proxy shim will be initialized with the factory deployer address as the owner, allowing only the factory deployer to upgrade the proxy,
// to the eventual factory implementation
(bytes memory proxyShimInitCode, bytes32 proxyShimSalt, address proxyShimAddress) = getProxyShimParams({
proxyDeployerAddress: proxyDeployerAddress,
proxyDeployerSalt: proxyDeployerSalt,
proxyShimSalt: proxyShimSalt,
proxySalt: proxySalt,
deterministicProxyAddress: deterministicProxyAddress
deployerAddress: deployerAddress,
proxyShimSaltSuffix: proxyShimSaltSuffix
});

return result;
// 3. Mine for a salt that can be used to deterministically create the factory proxy, given the proxy shim address, which is passed as the
// constructor argument, and the deployer, which is the new factory proxy deployer, which we know the address of deterministically
(bytes32 proxySalt, address deterministicProxyAddress) = getProxyParams({
proxyCreationCode: proxyCreationCode,
proxyShimAddress: proxyShimAddress,
proxyDeployerAddress: proxyDeployerAddress
});

return
DeterministicParams({
proxyDeployerCreationCode: proxyDeployerCreationCode,
proxyCreationCode: proxyCreationCode,
deployerAddress: deployerAddress,
proxyDeployerAddress: proxyDeployerAddress,
proxyDeployerSalt: proxyDeployerSalt,
proxyShimSalt: proxyShimSalt,
proxySalt: proxySalt,
deterministicProxyAddress: deterministicProxyAddress
});
}

error MismatchedAddress(address expected, address actual);
Expand Down
57 changes: 35 additions & 22 deletions test/deployer/NewFactoryProxyDeployer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,11 @@ contract DeterministicProxyDeployerTest is DeterministicDeployerScript, Test {
return DeterministicProxyDeployer(ZoraDeployerUtils.IMMUTABLE_CREATE2_FACTORY.safeCreate2(salt, type(DeterministicProxyDeployer).creationCode));
}

function test_proxyCanByDeployedAtDesiredAddress(uint32 nonce, bytes32 proxySalt) external {
vm.createSelectFork("zora_goerli", 1252119);
// ensure nonce is greater than current account's nonce

(address deployerAddress, uint256 deployerPrivateKey) = makeAddrAndKey("deployer");
bytes32 proxyDeployerSalt = ZoraDeployerUtils.FACTORY_DEPLOYER_DEPLOYMENT_SALT;

// now we can create the implementation, pointing it to the expected deterministic address:
function create1155FactoryImpl() internal returns (address) {
address mintFeeRecipient = makeAddr("mintFeeRecipient");
address factoryOwner = makeAddr("factorOwner");
address protocolRewards = makeAddr("protocolRewards");

bytes32 proxyShimSalt = saltWithAddressInFirst20Bytes(deployerAddress, 10);

// 1. Create implementation contracts based on deterministic factory proxy address

// create 1155 and factory impl, we can know the deterministic factor proxy address ahead of time:
(address factoryImplAddress, ) = ZoraDeployerUtils.deployNew1155AndFactoryImpl({
factoryProxyAddress: address(0),
mintFeeRecipient: mintFeeRecipient,
Expand All @@ -48,22 +36,40 @@ contract DeterministicProxyDeployerTest is DeterministicDeployerScript, Test {
fixedPriceMinter: IMinter1155(address(0))
});

vm.assume(nonce > vm.getNonce(deployerAddress));
// we set the nonce to a random value, to prove this doesn't affect the deterministic addrss
vm.setNonce(deployerAddress, nonce);
return factoryImplAddress;
}

function test_proxyCanByDeployedAtDesiredAddress(bytes32 proxySalt) external {
vm.createSelectFork("zora_goerli", 1252119);
// ensure nonce is greater than current account's nonce

(address deployerAddress, uint256 deployerPrivateKey) = makeAddrAndKey("deployer");
bytes32 proxyDeployerSalt = ZoraDeployerUtils.FACTORY_DEPLOYER_DEPLOYMENT_SALT;

// now we can create the implementation, pointing it to the expected deterministic address:
bytes32 proxyShimSalt = saltWithAddressInFirst20Bytes(deployerAddress, 10);

// 1. Create implementation contracts based on deterministic factory proxy address

// create 1155 and factory impl, we can know the deterministic factor proxy address ahead of time:
address factoryImplAddress = create1155FactoryImpl();

// 2. Create factory deployer at deterministic address
DeterministicProxyDeployer factoryProxyDeployer = _deployKnownZoraFactoryProxy(proxyDeployerSalt);

bytes memory factoryProxyCreationCode = type(Zora1155Factory).creationCode;
address mintFeeRecipient = makeAddr("mintFeeRecipient ");

bytes32 digest = factoryProxyDeployer.hashedDigestFactoryProxy(proxyShimSalt, proxySalt, factoryProxyCreationCode, factoryImplAddress, factoryOwner);
bytes32 digest = factoryProxyDeployer.hashedDigestFactoryProxy(
proxyShimSalt,
proxySalt,
factoryProxyCreationCode,
factoryImplAddress,
mintFeeRecipient
);

// sign the message
(uint8 v, bytes32 r, bytes32 s) = vm.sign(deployerPrivateKey, digest);

// combine into a single bytes array
bytes memory signature = abi.encodePacked(r, s, v);
bytes memory signature = signAndMakeBytes(digest, deployerPrivateKey);

address expectedFactoryProxyAddress = ZoraDeployerUtils.deterministicFactoryProxyAddress(proxyShimSalt, proxySalt, address(factoryProxyDeployer));

Expand All @@ -74,7 +80,7 @@ contract DeterministicProxyDeployerTest is DeterministicDeployerScript, Test {
factoryProxyCreationCode,
expectedFactoryProxyAddress,
factoryImplAddress,
factoryOwner,
mintFeeRecipient,
signature
);

Expand All @@ -83,6 +89,13 @@ contract DeterministicProxyDeployerTest is DeterministicDeployerScript, Test {
assertEq(factoryProxyAddress, expectedFactoryProxyAddress, "factory proxy address wrong");
}

function signAndMakeBytes(bytes32 digest, uint256 privateKey) internal returns (bytes memory) {
(uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest);

// combine into a single bytes array
return abi.encodePacked(r, s, v);
}

function test_genericContractCanByDeployedAtDesiredAddress(uint32 nonce) external {
vm.createSelectFork("zora_goerli", 1252119);

Expand Down

0 comments on commit c2ce689

Please sign in to comment.