Skip to content

Commit 166593c

Browse files
authored
fix: Restore implementation deployment using CreateX (#72)
1 parent b5e157f commit 166593c

File tree

9 files changed

+53
-25
lines changed

9 files changed

+53
-25
lines changed

docs/soldoc/src/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This project implements a cross-chain token bridge system for the RLC token usin
55
## Diagrams and source code docs (soldocs):
66

77
- [Diagrams](../../diagrams/)
8-
- [Source code docs](../../soldoc/)
8+
- [Source code docs](../../soldoc/src/SUMMARY.md)
99

1010
## Architecture
1111

script/RLCCrosschainToken.s.sol

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ contract Deploy is Script {
5858
) public returns (address) {
5959
bytes memory initData =
6060
abi.encodeWithSelector(RLCCrosschainToken.initialize.selector, name, symbol, initialAdmin, initialUpgrader);
61-
return UUPSProxyDeployer.deployUUPSProxyWithCreateX(
62-
"RLCCrosschainToken", "", initData, createxFactory, createxSalt
63-
);
61+
return UUPSProxyDeployer.deployUsingCreateX("RLCCrosschainToken", "", initData, createxFactory, createxSalt);
6462
}
6563
}

script/RLCLiquidityUnifier.s.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ contract Deploy is Script {
5757
bytes memory constructorData = abi.encode(rlcToken);
5858
bytes memory initData =
5959
abi.encodeWithSelector(RLCLiquidityUnifier.initialize.selector, initialAdmin, initialUpgrader);
60-
return UUPSProxyDeployer.deployUUPSProxyWithCreateX(
60+
return UUPSProxyDeployer.deployUsingCreateX(
6161
"RLCLiquidityUnifier", constructorData, initData, createxFactory, createxSalt
6262
);
6363
}

script/bridges/layerZero/IexecLayerZeroBridge.s.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ contract Deploy is Script {
5353
bytes memory initializeData = abi.encodeWithSelector(
5454
IexecLayerZeroBridge.initialize.selector, initialAdmin, initialUpgrader, initialPauser
5555
);
56-
return UUPSProxyDeployer.deployUUPSProxyWithCreateX(
56+
return UUPSProxyDeployer.deployUsingCreateX(
5757
"IexecLayerZeroBridge", constructorData, initializeData, createxFactory, createxSalt
5858
);
5959
}

script/lib/UUPSProxyDeployer.sol

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,25 @@ library UUPSProxyDeployer {
1717
Vm private constant vm = StdConstants.VM;
1818

1919
/**
20-
* Deploys a UUPS proxy contract and its implementation using the CreateX Factory
20+
* Deploys a UUPS proxy contract and its implementation in create2 mode using CreateX Factory.
2121
* @param contractName The name of the contract to deploy (used to fetch creation code)
2222
* @param constructorData The constructor arguments for the implementation contract
2323
* @param initializeData The initialization data for the proxy contract
24-
* @param createXFactory The address of the CreateX factory
25-
* @param salt The salt for deterministic deployment
24+
* @param createxFactory The address of the CreateX factory
25+
* @param createxSalt The salt for deterministic deployment
2626
* @return The address of the deployed proxy
2727
*/
28-
function deployUUPSProxyWithCreateX(
28+
function deployUsingCreateX(
2929
string memory contractName,
3030
bytes memory constructorData,
3131
bytes memory initializeData,
32-
address createXFactory,
33-
bytes32 salt
32+
address createxFactory,
33+
bytes32 createxSalt
3434
) internal returns (address) {
35-
ICreateX createX = ICreateX(createXFactory);
36-
address implementation = deployImplementation(contractName, constructorData, createX);
37-
address proxy = createX.deployCreate2AndInit(
38-
salt,
35+
address implementation =
36+
deployImplementationUsingCreateX(contractName, constructorData, createxFactory, createxSalt);
37+
address proxy = ICreateX(createxFactory).deployCreate2AndInit(
38+
createxSalt,
3939
abi.encodePacked(type(ERC1967Proxy).creationCode, abi.encode(implementation, "")), // initCode
4040
initializeData,
4141
ICreateX.Values({constructorAmount: 0, initCallAmount: 0}) // values for CreateX
@@ -45,18 +45,22 @@ library UUPSProxyDeployer {
4545
}
4646

4747
/**
48-
* Deploys the implementation contract using tradition `create`.
48+
* Deploys the implementation contract in create2 mode using CreateX factory.
4949
* @param contractName The name of the contract to deploy (used to fetch creation code)
5050
* @param constructorData The constructor arguments for the implementation contract
5151
* @param createxFactory The address of the CreateX factory
52+
* @param createxSalt The salt for deterministic deployment
5253
* @return The address of the deployed implementation contract
5354
*/
54-
function deployImplementation(string memory contractName, bytes memory constructorData, ICreateX createxFactory)
55-
internal
56-
returns (address)
57-
{
55+
function deployImplementationUsingCreateX(
56+
string memory contractName,
57+
bytes memory constructorData,
58+
address createxFactory,
59+
bytes32 createxSalt
60+
) internal returns (address) {
5861
bytes memory creationCode = vm.getCode(contractName);
59-
address implementation = createxFactory.deployCreate(abi.encodePacked(creationCode, constructorData));
62+
address implementation =
63+
ICreateX(createxFactory).deployCreate2(createxSalt, abi.encodePacked(creationCode, constructorData));
6064
console.log("Implementation deployed at:", implementation);
6165
return implementation;
6266
}

test/e2e/IexecLayerZeroBridgeScript.t.sol

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@ contract IexecLayerZeroBridgeScriptTest is Test {
101101
// TODO check that the proxy address is saved.
102102
}
103103

104+
function testFork_RevertWhen_TwoDeploymentsWithTheSameSalt() public {
105+
deployer.deploy(
106+
false, address(rlcCrosschainToken), params.lzEndpoint, admin, upgrader, pauser, params.createxFactory, salt
107+
);
108+
vm.expectRevert(abi.encodeWithSignature("FailedContractCreation(address)", params.createxFactory));
109+
deployer.deploy(
110+
false, address(rlcCrosschainToken), params.lzEndpoint, admin, upgrader, pauser, params.createxFactory, salt
111+
);
112+
}
113+
104114
// TODO: add tests for the configuration script.
105115

106116
function testFork_ConfigureContractCorrectly() public {

test/units/RLCCrosschainTokenScript.t.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,12 @@ contract RLCCrosschainTokenTest is Test {
4242

4343
// TODO check that the proxy address is saved.
4444
}
45+
46+
// Makes sure create2 deployment is well implemented.
47+
function test_RevertWhen_TwoDeploymentsWithTheSameSalt() public {
48+
address random = makeAddr("random");
49+
deployer.deploy(name, symbol, admin, upgrader, createx, salt);
50+
vm.expectRevert(abi.encodeWithSignature("FailedContractCreation(address)", createx));
51+
deployer.deploy("Foo", "BAR", random, random, createx, salt);
52+
}
4553
}

test/units/RLCLiquidityUnifierScript.t.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,12 @@ contract LiquidityUnifierTest is Test {
3535
rlcLiquidityUnifier.initialize(admin, upgrader);
3636
// TODO check that the proxy address is saved.
3737
}
38+
39+
// Makes sure create2 deployment is well implemented.
40+
function test_RevertWhen_TwoDeploymentsWithTheSameSalt() public {
41+
address random = makeAddr("random");
42+
deployer.deploy(rlcToken, admin, upgrader, createx, salt);
43+
vm.expectRevert(abi.encodeWithSignature("FailedContractCreation(address)", createx));
44+
deployer.deploy(rlcToken, random, random, createx, salt);
45+
}
3846
}

test/units/utils/TestUtils.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ library TestUtils {
4545

4646
// Deploy Liquidity Unifier
4747
rlcLiquidityUnifier = RLCLiquidityUnifier(
48-
UUPSProxyDeployer.deployUUPSProxyWithCreateX(
48+
UUPSProxyDeployer.deployUsingCreateX(
4949
"RLCLiquidityUnifier",
5050
abi.encode(rlcToken),
5151
abi.encodeWithSelector(RLCLiquidityUnifier.initialize.selector, initialAdmin, initialUpgrader),
@@ -56,7 +56,7 @@ library TestUtils {
5656

5757
// Deploy IexecLayerZeroBridgeAdapter
5858
iexecLayerZeroBridgeChainA = IexecLayerZeroBridge(
59-
UUPSProxyDeployer.deployUUPSProxyWithCreateX(
59+
UUPSProxyDeployer.deployUsingCreateX(
6060
"IexecLayerZeroBridge",
6161
abi.encode(true, rlcLiquidityUnifier, lzEndpointSource),
6262
abi.encodeWithSelector(
@@ -75,7 +75,7 @@ library TestUtils {
7575
);
7676
// Deploy IexecLayerZeroBridge
7777
iexecLayerZeroBridgeChainB = IexecLayerZeroBridge(
78-
UUPSProxyDeployer.deployUUPSProxyWithCreateX(
78+
UUPSProxyDeployer.deployUsingCreateX(
7979
"IexecLayerZeroBridge",
8080
abi.encode(false, rlcCrosschainToken, lzEndpointDestination),
8181
abi.encodeWithSelector(

0 commit comments

Comments
 (0)