Skip to content

Commit

Permalink
use create2 in BridgeCreator (#265)
Browse files Browse the repository at this point in the history
* docs: add note regarding reorg

* wip: use create2

* edit comment

* start over

* use create2 in bridge creator

* require rollup exists

* fix tests

* fix lint

* Revert "docs: add note regarding reorg"

This reverts commit d451b72.

* remove unnecessary args from salt

* fmt

* put the salt args back

* refactor: move hardcoded value to config

* refactor: minimumAssertionPeriod and validatorAfkBlocks in bold upgrade setting

* perf: remove onchain verification

* chore: update sigs

* refactor: remove hardcode in rollup initialize

* chore: update example

* test: new config param

* fix: format

* fix: BridgeTemplates

* fix: memory

* fix: format test

* feat: use msg.data hash as salt

* test: fix

* test: fix config

* fix: slither

* refactor: bridge creator create2Salt

* chore: remove unintended change

* chore: slither

---------

Co-authored-by: gzeon <[email protected]>
Co-authored-by: gzeon <[email protected]>
  • Loading branch information
3 people authored Dec 10, 2024
1 parent 2b13047 commit 799837d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
2 changes: 1 addition & 1 deletion slither.db.json

Large diffs are not rendered by default.

28 changes: 23 additions & 5 deletions src/rollup/BridgeCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,22 @@ contract BridgeCreator is Ownable {
}

function _createBridge(
bytes32 create2Salt,
address adminProxy,
BridgeTemplates memory templates,
bool isDelayBufferable
) internal returns (BridgeContracts memory) {
BridgeContracts memory frame;
frame.bridge = IBridge(
address(new TransparentUpgradeableProxy(address(templates.bridge), adminProxy, ""))
address(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.bridge), adminProxy, ""
)
)
);
frame.sequencerInbox = ISequencerInbox(
address(
new TransparentUpgradeableProxy(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(
isDelayBufferable
? templates.delayBufferableSequencerInbox
Expand All @@ -87,15 +92,25 @@ contract BridgeCreator is Ownable {
)
);
frame.inbox = IInboxBase(
address(new TransparentUpgradeableProxy(address(templates.inbox), adminProxy, ""))
address(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.inbox), adminProxy, ""
)
)
);
frame.rollupEventInbox = IRollupEventInbox(
address(
new TransparentUpgradeableProxy(address(templates.rollupEventInbox), adminProxy, "")
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.rollupEventInbox), adminProxy, ""
)
)
);
frame.outbox = IOutbox(
address(new TransparentUpgradeableProxy(address(templates.outbox), adminProxy, ""))
address(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.outbox), adminProxy, ""
)
)
);
return frame;
}
Expand All @@ -107,11 +122,14 @@ contract BridgeCreator is Ownable {
ISequencerInbox.MaxTimeVariation calldata maxTimeVariation,
BufferConfig calldata bufferConfig
) external returns (BridgeContracts memory) {
// use create2 salt to ensure deterministic addresses
bytes32 create2Salt = keccak256(abi.encode(msg.data, msg.sender));
// create delay bufferable sequencer inbox if threshold is non-zero
bool isDelayBufferable = bufferConfig.threshold != 0;

// create ETH-based bridge if address zero is provided for native token, otherwise create ERC20-based bridge
BridgeContracts memory frame = _createBridge(
create2Salt,
adminProxy,
nativeToken == address(0) ? ethBasedTemplates : erc20BasedTemplates,
isDelayBufferable
Expand Down
25 changes: 25 additions & 0 deletions test/foundry/BridgeCreator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ contract BridgeCreatorTest is Test {
max: type(uint64).max,
replenishRateInBasis: 0
});

BridgeCreator.BridgeContracts memory contracts =
creator.createBridge(proxyAdmin, rollup, nativeToken, timeVars, bufferConfig);
(
Expand Down Expand Up @@ -245,4 +246,28 @@ contract BridgeCreatorTest is Test {
assertEq(address(outbox.bridge()), address(bridge), "Invalid bridge ref");
assertEq(address(outbox.rollup()), rollup, "Invalid rollup ref");
}

function test_canOnlyDeployOnce() external {
address proxyAdmin = address(300);
address rollup = address(301);
address nativeToken =
address(new ERC20PresetFixedSupply("Appchain Token", "App", 1_000_000, address(this)));
ISequencerInbox.MaxTimeVariation memory timeVars =
ISequencerInbox.MaxTimeVariation(10, 20, 30, 40);
BufferConfig memory bufferConfig = BufferConfig({
threshold: type(uint64).max,
max: type(uint64).max,
replenishRateInBasis: 0
});

creator.createBridge(proxyAdmin, rollup, nativeToken, timeVars, bufferConfig);

// can only deploy once from the same address and config
vm.expectRevert();
creator.createBridge(proxyAdmin, rollup, nativeToken, timeVars, bufferConfig);

// can deploy from a different address
vm.prank(address(101));
creator.createBridge(proxyAdmin, rollup, nativeToken, timeVars, bufferConfig);
}
}

0 comments on commit 799837d

Please sign in to comment.