Skip to content
This repository was archived by the owner on Oct 21, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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
27 changes: 14 additions & 13 deletions py_builder_relayer_client/builder/derive.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from eth_abi import encode
from eth_utils import to_bytes, to_checksum_address, keccak

ERC1967_CONST1 = "0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3"
ERC1967_CONST2 = "0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076"
ERC1967_PREFIX = 0x61003D3D8160233D3973
ERC1967_BEACON_CONST1 = "0x60195155f3363d3d373d3d363d602036600436635c60da"
ERC1967_BEACON_CONST2 = "0x1b60e01b36527fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6c"
ERC1967_BEACON_CONST3 = "0xb3582b35133d50545afa5036515af43d6000803e604d573d6000fd5b3d6000f3"
ERC1967_BEACON_PREFIX = 0x6100523D8160233D3973


def get_create2_address(bytecode_hash: str, from_address: str, salt: bytes) -> str:
Expand All @@ -18,28 +19,28 @@ def get_create2_address(bytecode_hash: str, from_address: str, salt: bytes) -> s
return to_checksum_address(address_hash[-20:].hex())


def init_code_hash_erc1967(implementation: str, args: bytes) -> str:
implementation = to_checksum_address(implementation)
def init_code_hash_erc1967_beacon_proxy(beacon: str, args: bytes) -> str:
beacon = to_checksum_address(beacon)
n = len(args)
combined = ERC1967_PREFIX + (n << 56)
combined = ERC1967_BEACON_PREFIX + (n << 56)
init_code = (
combined.to_bytes(10, "big")
+ to_bytes(hexstr=implementation)
+ to_bytes(hexstr="0x6009")
+ to_bytes(hexstr=ERC1967_CONST2)
+ to_bytes(hexstr=ERC1967_CONST1)
+ to_bytes(hexstr=beacon)
+ to_bytes(hexstr=ERC1967_BEACON_CONST1)
+ to_bytes(hexstr=ERC1967_BEACON_CONST2)
+ to_bytes(hexstr=ERC1967_BEACON_CONST3)
+ args
)
return "0x" + keccak(init_code).hex()


def derive_deposit_wallet(owner: str, factory: str, implementation: str) -> str:
def derive_deposit_wallet(owner: str, factory: str, beacon: str) -> str:
owner = to_checksum_address(owner)
factory = to_checksum_address(factory)
implementation = to_checksum_address(implementation)
beacon = to_checksum_address(beacon)

wallet_id = to_bytes(hexstr=owner).rjust(32, b"\x00")
args = encode(["address", "bytes32"], [factory, wallet_id])
salt = keccak(args)
bytecode_hash = init_code_hash_erc1967(implementation, args)
bytecode_hash = init_code_hash_erc1967_beacon_proxy(beacon, args)
return get_create2_address(bytecode_hash=bytecode_hash, from_address=factory, salt=salt)
2 changes: 1 addition & 1 deletion py_builder_relayer_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def derive_deposit_wallet(self):
return derive_deposit_wallet(
self.signer.address(),
self.contract_config.deposit_wallet_factory,
self.contract_config.deposit_wallet_implementation,
self.contract_config.deposit_wallet_beacon,
)

def get_expected_deposit_wallet(self):
Expand Down
12 changes: 6 additions & 6 deletions py_builder_relayer_client/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
@dataclass
class ContractConfig:
deposit_wallet_factory: str
deposit_wallet_implementation: str
deposit_wallet_beacon: str


DEPOSIT_WALLET_FACTORY = to_checksum_address("0x3DaBe8f032833CE42CC26d9149660E6f596759C5")
DEPOSIT_WALLET_IMPLEMENTATION = to_checksum_address("0xFB2f5D822Ecb062dE63a7B830C5e83C994698851")
DEPOSIT_WALLET_FACTORY = to_checksum_address("0x2CcdC6C5dDcd895aFcCD259F291de9b618A5cA6c")
DEPOSIT_WALLET_BEACON = to_checksum_address("0x74a618eBdd62Ff8579A8FE94f5B888d7623b9C35")

CONFIG = {
137: ContractConfig(
deposit_wallet_factory=DEPOSIT_WALLET_FACTORY,
deposit_wallet_implementation=DEPOSIT_WALLET_IMPLEMENTATION,
deposit_wallet_beacon=DEPOSIT_WALLET_BEACON,
),
80002: ContractConfig(
deposit_wallet_factory=DEPOSIT_WALLET_FACTORY,
deposit_wallet_implementation=DEPOSIT_WALLET_IMPLEMENTATION,
deposit_wallet_beacon=DEPOSIT_WALLET_BEACON,
),
}

Expand All @@ -33,4 +33,4 @@ def get_contract_config(chain_id: int) -> ContractConfig:


def is_deposit_wallet_config_valid(config: ContractConfig) -> bool:
return bool(config.deposit_wallet_factory) and bool(config.deposit_wallet_implementation)
return bool(config.deposit_wallet_factory) and bool(config.deposit_wallet_beacon)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="kuest-py-builder-relayer-client",
version="2.0.4",
version="2.0.5",
author="Kuest Engineering",
author_email="engineering@kuest.com",
maintainer="Kuest Engineering",
Expand Down
4 changes: 2 additions & 2 deletions tests/builder/test_derive.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ def test_derive_deposit_wallet(self):
wallet = derive_deposit_wallet(
owner,
config.deposit_wallet_factory,
config.deposit_wallet_implementation,
config.deposit_wallet_beacon,
)
self.assertEqual("0x053258Cfb6124a089363F89dA04b2eFa39b34e2d", wallet)
self.assertEqual("0xF3ab66D34F0B14C9a4f8564Ec8baaBBf51ad0Fd6", wallet)
6 changes: 3 additions & 3 deletions tests/config/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ def test_get_contract_config(self):
for chain_id in (137, 80002):
cfg = get_contract_config(chain_id)
self.assertEqual(
"0x3DaBe8f032833CE42CC26d9149660E6f596759C5",
"0x2CcdC6C5dDcd895aFcCD259F291de9b618A5cA6c",
cfg.deposit_wallet_factory,
)
self.assertEqual(
"0xFB2f5D822Ecb062dE63a7B830C5e83C994698851",
cfg.deposit_wallet_implementation,
"0x74a618eBdd62Ff8579A8FE94f5B888d7623b9C35",
cfg.deposit_wallet_beacon,
)

with self.assertRaises(RelayerClientException):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_client_deposit_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# Public Hardhat/Anvil fixture key. This is not a live credential.
TEST_PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
ADDRESS = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
WALLET = "0x053258Cfb6124a089363F89dA04b2eFa39b34e2d"
WALLET = "0xF3ab66D34F0B14C9a4f8564Ec8baaBBf51ad0Fd6"
TOKEN = "0x0000000000000000000000000000000000000001"
APPROVE_CALLDATA = "0x095ea7b30000000000000000000000000000000000000000000000000000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

Expand Down