From 35ec7643c61b7cb06811759f5526b41c853f5504 Mon Sep 17 00:00:00 2001 From: atarpara Date: Sat, 29 Aug 2026 11:57:14 +0530 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=90=9E=20ERC1967BeaconProxy=20initial?= =?UTF-8?q?ization=20call?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/ext/zksync/ERC1967BeaconProxy.sol | 25 ++++++++++++++++----- test/ext/zksync/ERC1967Factory.t.sol | 8 +++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/utils/ext/zksync/ERC1967BeaconProxy.sol b/src/utils/ext/zksync/ERC1967BeaconProxy.sol index ad7f5fe17e..94df6c24a7 100644 --- a/src/utils/ext/zksync/ERC1967BeaconProxy.sol +++ b/src/utils/ext/zksync/ERC1967BeaconProxy.sol @@ -19,8 +19,8 @@ contract ERC1967BeaconProxy { /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ - /// @dev The ERC-1967 storage slot for the implementation in the proxy. - /// `uint256(keccak256("eip1967.proxy.implementation")) - 1`. + /// @dev The ERC-1967 storage slot for the beacon in the proxy. + /// `uint256(keccak256("eip1967.proxy.beacon")) - 1`. bytes32 internal constant _ERC1967_BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; @@ -57,9 +57,24 @@ contract ERC1967BeaconProxy { } // Deployer workflow. if eq(caller(), sload(_ERC1967_BEACON_PROXY_DEPLOYER_SLOT)) { - sstore(_ERC1967_BEACON_SLOT, calldataload(0x00)) - // Emit the {Upgraded} event. - log2(0x00, 0x00, _BEACON_UPGRADED_EVENT_SIGNATURE, calldataload(0x00)) + let beacon := calldataload(0x00) + sstore(_ERC1967_BEACON_SLOT, beacon) + // Make the initialization call + if gt(calldatasize(), 0x20) { + mstore(0x00, 0x5c60da1b) // `implementation()`. + let t := staticcall(gas(), beacon, 0x1c, 0x04, 0x00, 0x20) + if iszero(and(gt(returndatasize(), 0x1f), t)) { revert(0x00, 0x00) } + let implementation := mload(0x00) + let n := sub(calldatasize(), 0x20) + calldatacopy(0x00, 0x20, n) + if iszero(delegatecall(gas(), implementation, 0x00, n, 0x00, 0x00)) { + // Bubble up the revert if the call reverts. + returndatacopy(0x00, 0x00, returndatasize()) + revert(0x00, returndatasize()) + } + } + // Emit the {BeaconUpgraded} event. + log2(0x00, 0x00, _BEACON_UPGRADED_EVENT_SIGNATURE, beacon) stop() // End the context. } // Query the beacon. diff --git a/test/ext/zksync/ERC1967Factory.t.sol b/test/ext/zksync/ERC1967Factory.t.sol index 69a92179ed..9694e82a88 100644 --- a/test/ext/zksync/ERC1967Factory.t.sol +++ b/test/ext/zksync/ERC1967Factory.t.sol @@ -92,6 +92,14 @@ contract ERC1967FactoryTest is SoladyTest { _checkBehavesLikeProxy(beaconProxy); } + + function testDeployBeaconProxyDeterministicAndCall() public { + address beacon = factory.deployBeacon(address(implementation), address(this)); + bytes memory data = + abi.encodeWithSelector(SampleImplementation.setX.selector, uint256(69)); + address beaconProxy = factory.deployBeaconProxyAndCall(beacon, data); + assertEq(SampleImplementation(beaconProxy).x(), 69); + } function _checkBehavesLikeProxy(address instance) internal { assertTrue(instance != address(0)); From 675bff3e4a4add893e35f681b88478e6387a84a4 Mon Sep 17 00:00:00 2001 From: atarpara Date: Sat, 29 Aug 2026 14:26:36 +0530 Subject: [PATCH 2/2] forge fmt --- test/ext/zksync/ERC1967Factory.t.sol | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/ext/zksync/ERC1967Factory.t.sol b/test/ext/zksync/ERC1967Factory.t.sol index 9694e82a88..ed4169ee6d 100644 --- a/test/ext/zksync/ERC1967Factory.t.sol +++ b/test/ext/zksync/ERC1967Factory.t.sol @@ -92,11 +92,10 @@ contract ERC1967FactoryTest is SoladyTest { _checkBehavesLikeProxy(beaconProxy); } - + function testDeployBeaconProxyDeterministicAndCall() public { address beacon = factory.deployBeacon(address(implementation), address(this)); - bytes memory data = - abi.encodeWithSelector(SampleImplementation.setX.selector, uint256(69)); + bytes memory data = abi.encodeWithSelector(SampleImplementation.setX.selector, uint256(69)); address beaconProxy = factory.deployBeaconProxyAndCall(beacon, data); assertEq(SampleImplementation(beaconProxy).x(), 69); }