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(Multichain): zk sync creation #4334

Merged
merged 1 commit into from
Oct 8, 2024
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
30 changes: 30 additions & 0 deletions src/components/new-safe/create/logic/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,5 +320,35 @@ describe('create/logic', () => {
factoryAddress: getProxyFactoryDeployment({ version: '1.4.1', network: '137' })?.defaultAddress,
})
})

it('should use l2 masterCopy and no migration on zkSync', () => {
const safeSetup = {
owners: [faker.finance.ethereumAddress()],
threshold: 1,
}
expect(
createNewUndeployedSafeWithoutSalt(
'1.3.0',
safeSetup,
chainBuilder()
.with({ chainId: '324' })
// Multichain and 1.4.1 creation is toggled off
.with({ features: [FEATURES.COUNTERFACTUAL] as any })
.with({ l2: true })
.build(),
),
).toEqual({
safeAccountConfig: {
...safeSetup,
fallbackHandler: getFallbackHandlerDeployment({ version: '1.3.0', network: '324' })?.networkAddresses['324'],
to: ZERO_ADDRESS,
data: EMPTY_DATA,
paymentReceiver: ECOSYSTEM_ID_ADDRESS,
},
safeVersion: '1.3.0',
masterCopy: getSafeL2SingletonDeployment({ version: '1.3.0', network: '324' })?.networkAddresses['324'],
factoryAddress: getProxyFactoryDeployment({ version: '1.3.0', network: '324' })?.networkAddresses['324'],
})
})
})
})
3 changes: 1 addition & 2 deletions src/components/new-safe/create/logic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ export const computeNewSafeAddress = async (
saltNonce: props.saltNonce,
safeVersion: safeVersion ?? getLatestSafeVersion(chain),
},
isL1SafeSingleton: true,
})
}

Expand Down Expand Up @@ -211,7 +210,7 @@ export const createNewUndeployedSafeWithoutSalt = (
version: safeVersion,
network: chain.chainId,
})
const fallbackHandlerAddress = fallbackHandlerDeployment?.defaultAddress
const fallbackHandlerAddress = fallbackHandlerDeployment?.networkAddresses[chain.chainId]
const safeL2Deployment = getSafeL2SingletonDeployment({ version: safeVersion, network: chain.chainId })
const safeL2Address = safeL2Deployment?.networkAddresses[chain.chainId]

Expand Down
26 changes: 21 additions & 5 deletions src/components/new-safe/create/logic/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ import { sameAddress } from '@/utils/addresses'
import { createWeb3ReadOnly, getRpcServiceUrl } from '@/hooks/wallets/web3'
import { type ReplayedSafeProps } from '@/store/slices'
import { predictAddressBasedOnReplayData } from '@/components/welcome/MyAccounts/utils/multiChainSafe'
import chains from '@/config/chains'
import { computeNewSafeAddress } from '.'

export const getAvailableSaltNonce = async (
customRpcs: {
[chainId: string]: string
},
replayedSafe: ReplayedSafeProps,
chains: ChainInfo[],
chainInfos: ChainInfo[],
// All addresses from the sidebar disregarding the chain. This is an optimization to reduce RPC calls
knownSafeAddresses: string[],
): Promise<string> => {
let isAvailableOnAllChains = true
const allRPCs = chains.map((chain) => {
const allRPCs = chainInfos.map((chain) => {
const rpcUrl = customRpcs?.[chain.chainId] || getRpcServiceUrl(chain.rpcUri)
// Turn into Eip1993Provider
return {
Expand All @@ -24,7 +26,7 @@ export const getAvailableSaltNonce = async (
}
})

for (const chain of chains) {
for (const chain of chainInfos) {
const rpcUrl = allRPCs.find((rpc) => chain.chainId === rpc.chainId)?.rpcUrl
if (!rpcUrl) {
throw new Error(`No RPC available for ${chain.chainName}`)
Expand All @@ -33,7 +35,21 @@ export const getAvailableSaltNonce = async (
if (!web3ReadOnly) {
throw new Error('Could not initiate RPC')
}
const safeAddress = await predictAddressBasedOnReplayData(replayedSafe, web3ReadOnly)
let safeAddress: string
if (chain.chainId === chains['zksync']) {
// ZK-sync is using a different create2 method which is supported by the SDK
safeAddress = await computeNewSafeAddress(
rpcUrl,
{
safeAccountConfig: replayedSafe.safeAccountConfig,
saltNonce: replayedSafe.saltNonce,
},
chain,
replayedSafe.safeVersion,
)
} else {
safeAddress = await predictAddressBasedOnReplayData(replayedSafe, web3ReadOnly)
}
const isKnown = knownSafeAddresses.some((knownAddress) => sameAddress(knownAddress, safeAddress))
if (isKnown || (await isSmartContract(safeAddress, web3ReadOnly))) {
// We found a chain where the nonce is used up
Expand All @@ -47,7 +63,7 @@ export const getAvailableSaltNonce = async (
return getAvailableSaltNonce(
customRpcs,
{ ...replayedSafe, saltNonce: (Number(replayedSafe.saltNonce) + 1).toString() },
chains,
chainInfos,
knownSafeAddresses,
)
}
Expand Down
20 changes: 18 additions & 2 deletions src/components/new-safe/create/steps/ReviewStep/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getTotalFeeFormatted } from '@/hooks/useGasPrice'
import type { StepRenderProps } from '@/components/new-safe/CardStepper/useCardStepper'
import type { NewSafeFormData } from '@/components/new-safe/create'
import {
computeNewSafeAddress,
createNewSafe,
createNewUndeployedSafeWithoutSalt,
relaySafeCreation,
Expand Down Expand Up @@ -47,9 +48,10 @@ import { selectRpc } from '@/store/settingsSlice'
import { AppRoutes } from '@/config/routes'
import { type ReplayedSafeProps } from '@/store/slices'
import { predictAddressBasedOnReplayData } from '@/components/welcome/MyAccounts/utils/multiChainSafe'
import { createWeb3ReadOnly } from '@/hooks/wallets/web3'
import { createWeb3ReadOnly, getRpcServiceUrl } from '@/hooks/wallets/web3'
import { type DeploySafeProps } from '@safe-global/protocol-kit'
import { updateAddressBook } from '../../logic/address-book'
import chains from '@/config/chains'

export const NetworkFee = ({
totalFee,
Expand Down Expand Up @@ -227,7 +229,21 @@ const ReviewStep = ({ data, onSubmit, onBack, setStep }: StepRenderProps<NewSafe
const provider = createWeb3ReadOnly(chain, customRpcUrl)
if (!provider) return

const safeAddress = await predictAddressBasedOnReplayData(replayedSafeWithNonce, provider)
let safeAddress: string

if (chain.chainId === chains['zksync']) {
safeAddress = await computeNewSafeAddress(
customRpcUrl || getRpcServiceUrl(chain.rpcUri),
{
safeAccountConfig: replayedSafeWithNonce.safeAccountConfig,
saltNonce: nextAvailableNonce,
},
chain,
replayedSafeWithNonce.safeVersion,
)
} else {
safeAddress = await predictAddressBasedOnReplayData(replayedSafeWithNonce, provider)
}

for (const network of data.networks) {
await createSafe(network, replayedSafeWithNonce, safeAddress)
Expand Down
Loading