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

fix: use bytecode-hash from creationCode in proxy-factory #38

Merged
merged 5 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ deploy-polygon :; forge script script/DeployTransparentProxyFactory.s.sol:Deploy
deploy-avalanche :; forge script script/DeployTransparentProxyFactory.s.sol:DeployAvalanche --rpc-url avalanche --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-optimism :; forge script script/DeployTransparentProxyFactory.s.sol:DeployOptimism --rpc-url optimism --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-arbitrum :; forge script script/DeployTransparentProxyFactory.s.sol:DeployArbitrum --rpc-url arbitrum --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-zksync :; forge script script-zksync/DeployTransparentProxyFactoryZkSync.s.sol:DeployZkSync --zksync --system-mode=true --rpc-url zksync --broadcast --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv

# ---------------------------------------------- BASE SCRIPT CONFIGURATION ---------------------------------------------

Expand Down
6 changes: 4 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
[profile.default]
src = 'src'
tests = 'tests'
script = 'script'
out = 'out'
libs = ['lib']
remappings = []

[profile.zksync]
src = 'src-zksync'
test = 'test-zksync'
script = 'script-zksync'
libs = ['lib']
solc="0.8.19"
solc="0.8.24"
evm_version = "cancun"

[profile.zksync.zksync]
fallback_oz = true
mode = "3"
zksolc="1.4.1"


# See more config options https://github.com/gakonst/foundry/tree/master/config
[rpc_endpoints]
ethereum = "${RPC_MAINNET}"
Expand Down
13 changes: 13 additions & 0 deletions script-zksync/DeployTransparentProxyFactoryZkSync.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Script} from 'forge-std/Script.sol';
import {TransparentProxyFactoryZkSync} from '../src-zksync/contracts/transparent-proxy/TransparentProxyFactoryZkSync.sol';

contract DeployZkSync is Script {
function run() external {
vm.startBroadcast();
new TransparentProxyFactoryZkSync();
vm.stopBroadcast();
}
}
Original file line number Diff line number Diff line change
@@ -1,75 +1,60 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
pragma solidity >=0.8.24;

import {TransparentProxyFactoryBase, ITransparentProxyFactory} from '../../../src/contracts/transparent-proxy/TransparentProxyFactoryBase.sol';
import {TransparentProxyFactoryBase} from '../../../src/contracts/transparent-proxy/TransparentProxyFactoryBase.sol';
import {ITransparentProxyFactoryZkSync} from './interfaces/ITransparentProxyFactoryZkSync.sol';

/**
* @title TransparentProxyFactoryZkSync
* @author BGD Labs
* @notice Factory contract to create transparent proxies, both with CREATE and CREATE2
* @notice Factory contract specific to zkSync to create transparent proxies, both with CREATE and CREATE2
* @dev `create()` and `createDeterministic()` are not unified for clearer interface, and at the same
* time allowing `createDeterministic()` with salt == 0
* @dev Highly recommended to pass as `admin` on creation an OZ ProxyAdmin instance
* @dev This contract needs solc=0.8.19 and zksolc=1.4.1 as codeHashes are specifically made for those versions
**/
contract TransparentProxyFactoryZkSync is
TransparentProxyFactoryBase,
ITransparentProxyFactoryZkSync
{
/// @inheritdoc ITransparentProxyFactoryZkSync
bytes32 public constant TRANSPARENT_UPGRADABLE_PROXY_INIT_CODE_HASH =
0x010001b73fa7f2c39ea2d9c597a419e15436fc9d3e00e032410072fb94ad95e1;

/// @inheritdoc ITransparentProxyFactoryZkSync
bytes32 public constant PROXY_ADMIN_INIT_CODE_HASH =
0x010000e7f9a8b61da13fe7e27804d9f641f5f8db05b07df720973af749a01ac1;

/// @inheritdoc ITransparentProxyFactoryZkSync
bytes32 public constant ZKSYNC_CREATE2_PREFIX = keccak256('zksyncCreate2');

/// @inheritdoc ITransparentProxyFactory
function predictCreateDeterministic(
address logic,
address admin,
bytes calldata data,
bytes32 salt
) public view override returns (address) {
return
_predictCreate2Address(
address(this),
salt,
TRANSPARENT_UPGRADABLE_PROXY_INIT_CODE_HASH,
abi.encode(logic, admin, data)
);
}

/// @inheritdoc ITransparentProxyFactory
function predictCreateDeterministicProxyAdmin(bytes32 salt)
public
view
override
returns (address)
{
return _predictCreate2Address(address(this), salt, PROXY_ADMIN_INIT_CODE_HASH, abi.encode());
}

function _predictCreate2Address(
address sender,
bytes32 salt,
bytes32 creationCodeHash,
bytes memory creationCode,
bytes memory constructorInput
) internal pure returns (address) {
) internal pure override returns (address) {
bytes32 addressHash = keccak256(
bytes.concat(
ZKSYNC_CREATE2_PREFIX,
bytes32(uint256(uint160(sender))),
salt,
creationCodeHash,
bytes32(_sliceBytes(creationCode, 36, 32)),
keccak256(constructorInput)
)
);

return address(uint160(uint256(addressHash)));
}

function _sliceBytes(
bytes memory data,
uint256 start,
uint256 length
) internal pure returns (bytes memory) {
require(start + length <= data.length, 'Slice out of bounds');

bytes memory result = new bytes(length);
assembly {
let dataPtr := add(data, 32)
let resultPtr := add(result, 32)

// Use mcopy to efficiently copy the slice
mcopy(resultPtr, add(dataPtr, start), length)

mstore(result, length)
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,6 @@
pragma solidity >=0.8.0;

interface ITransparentProxyFactoryZkSync {
/**
* @notice method to get the hash of creation bytecode of the TransparentUpgradableProxy contract
* @return hashed of creation bytecode of the TransparentUpgradableProxy contract
*/
function TRANSPARENT_UPGRADABLE_PROXY_INIT_CODE_HASH() external returns (bytes32);

/**
* @notice method to get the hash of creation bytecode of the ProxyAdmin contract
* @return hashed of creation bytecode of the ProxyAdmin contract
*/
function PROXY_ADMIN_INIT_CODE_HASH() external returns (bytes32);

/**
* @notice method to get the zksync create2 prefix used for create2 address derivation in zksync
* @return create2 prefix used for create2 address derivation
Expand Down
34 changes: 4 additions & 30 deletions src/contracts/transparent-proxy/TransparentProxyFactory.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import {TransparentProxyFactoryBase, ITransparentProxyFactory, ProxyAdmin, TransparentUpgradeableProxy} from './TransparentProxyFactoryBase.sol';
import {TransparentProxyFactoryBase} from './TransparentProxyFactoryBase.sol';

/**
* @title TransparentProxyFactory
Expand All @@ -12,44 +12,18 @@ import {TransparentProxyFactoryBase, ITransparentProxyFactory, ProxyAdmin, Trans
* @dev Highly recommended to pass as `admin` on creation an OZ ProxyAdmin instance
**/
contract TransparentProxyFactory is TransparentProxyFactoryBase {
/// @inheritdoc ITransparentProxyFactory
function predictCreateDeterministic(
address logic,
address admin,
bytes calldata data,
bytes32 salt
) public view override returns (address) {
return
_predictCreate2Address(
address(this),
salt,
type(TransparentUpgradeableProxy).creationCode,
abi.encode(logic, admin, data)
);
}

/// @inheritdoc ITransparentProxyFactory
function predictCreateDeterministicProxyAdmin(bytes32 salt)
public
view
override
returns (address)
{
return _predictCreate2Address(address(this), salt, type(ProxyAdmin).creationCode, abi.encode());
}

function _predictCreate2Address(
address creator,
bytes32 salt,
bytes memory creationCode,
bytes memory contructorArgs
) internal pure returns (address) {
bytes memory constructorArgs
) internal pure override returns (address) {
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff),
creator,
salt,
keccak256(abi.encodePacked(creationCode, contructorArgs))
keccak256(abi.encodePacked(creationCode, constructorArgs))
)
);

Expand Down
21 changes: 19 additions & 2 deletions src/contracts/transparent-proxy/TransparentProxyFactoryBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,25 @@ abstract contract TransparentProxyFactoryBase is ITransparentProxyFactory {
address admin,
bytes calldata data,
bytes32 salt
) public view virtual returns (address);
) public view returns (address) {
return
_predictCreate2Address(
address(this),
salt,
type(TransparentUpgradeableProxy).creationCode,
abi.encode(logic, admin, data)
);
}

/// @inheritdoc ITransparentProxyFactory
function predictCreateDeterministicProxyAdmin(bytes32 salt) public view virtual returns (address);
function predictCreateDeterministicProxyAdmin(bytes32 salt) public view returns (address) {
return _predictCreate2Address(address(this), salt, type(ProxyAdmin).creationCode, abi.encode());
}

function _predictCreate2Address(
address creator,
bytes32 salt,
bytes memory creationCode,
bytes memory constructorArgs
) internal pure virtual returns (address);
}
2 changes: 1 addition & 1 deletion test-zksync/TransparentProxyFactoryZkSync.t.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma solidity ^0.8.24;

import {Test} from 'forge-std/Test.sol';
import {TransparentProxyFactoryZkSync} from '../src-zksync/contracts/transparent-proxy/TransparentProxyFactoryZkSync.sol';
Expand Down
Loading