From 89906f30a3701f529546baf4041fface2c3c1ed3 Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:52:03 +0100 Subject: [PATCH 1/2] Fix: use recommendedMasterCopyVersion only for Safe upgrades --- .../components/settings/ContractVersion/index.tsx | 2 +- apps/web/src/features/multichain/utils/utils.ts | 13 +++++++------ apps/web/src/services/tx/safeUpdateParams.ts | 2 +- apps/web/src/utils/chains.ts | 7 +++++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/apps/web/src/components/settings/ContractVersion/index.tsx b/apps/web/src/components/settings/ContractVersion/index.tsx index 63450e4dc1..2879edab1d 100644 --- a/apps/web/src/components/settings/ContractVersion/index.tsx +++ b/apps/web/src/components/settings/ContractVersion/index.tsx @@ -29,7 +29,7 @@ export const ContractVersion = () => { const showUpdateDialog = safeMasterCopy?.deployer === MasterCopyDeployer.GNOSIS && needsUpdate const isLatestVersion = safe.version && !showUpdateDialog - const latestSafeVersion = getLatestSafeVersion(currentChain) + const latestSafeVersion = getLatestSafeVersion(currentChain, true) return ( <> diff --git a/apps/web/src/features/multichain/utils/utils.ts b/apps/web/src/features/multichain/utils/utils.ts index be50ff10f4..040fc00fff 100644 --- a/apps/web/src/features/multichain/utils/utils.ts +++ b/apps/web/src/features/multichain/utils/utils.ts @@ -121,15 +121,16 @@ export const predictAddressBasedOnReplayData = async (safeCreationData: Replayed return getCreate2Address(safeCreationData.factoryAddress, salt, keccak256(initCode)) } +const canMultichain = (chain: ChainInfo) => { + const MIN_SAFE_VERSION = '1.4.1' + return hasFeature(chain, FEATURES.COUNTERFACTUAL) && semverSatisfies(LATEST_SAFE_VERSION, `>=${MIN_SAFE_VERSION}`) +} + export const hasMultiChainCreationFeatures = (chain: ChainInfo): boolean => { - return hasFeature(chain, FEATURES.MULTI_CHAIN_SAFE_CREATION) && hasFeature(chain, FEATURES.COUNTERFACTUAL) + return hasFeature(chain, FEATURES.MULTI_CHAIN_SAFE_CREATION) && canMultichain(chain) } export const hasMultiChainAddNetworkFeature = (chain: ChainInfo | undefined): boolean => { if (!chain) return false - return ( - hasFeature(chain, FEATURES.MULTI_CHAIN_SAFE_ADD_NETWORK) && - hasFeature(chain, FEATURES.COUNTERFACTUAL) && - semverSatisfies(chain.recommendedMasterCopyVersion || LATEST_SAFE_VERSION, '>=1.4.1') - ) + return hasFeature(chain, FEATURES.MULTI_CHAIN_SAFE_ADD_NETWORK) && canMultichain(chain) } diff --git a/apps/web/src/services/tx/safeUpdateParams.ts b/apps/web/src/services/tx/safeUpdateParams.ts index d90c71b0d3..1eda91e09b 100644 --- a/apps/web/src/services/tx/safeUpdateParams.ts +++ b/apps/web/src/services/tx/safeUpdateParams.ts @@ -46,7 +46,7 @@ export const createUpdateSafeTxs = async (safe: SafeInfo, chain: ChainInfo): Pro ).getAddress() const currentReadOnlySafeContract = await getReadOnlyGnosisSafeContract(chain, safe.version) - const updatedReadOnlySafeContract = await getReadOnlyGnosisSafeContract(chain, getLatestSafeVersion(chain)) + const updatedReadOnlySafeContract = await getReadOnlyGnosisSafeContract(chain, getLatestSafeVersion(chain, true)) // @ts-expect-error this was removed in 1.3.0 but we need to support it for older safe versions const changeMasterCopyCallData = currentReadOnlySafeContract.encode('changeMasterCopy', [latestMasterCopyAddress]) diff --git a/apps/web/src/utils/chains.ts b/apps/web/src/utils/chains.ts index c164a298a9..8d7534b7c1 100644 --- a/apps/web/src/utils/chains.ts +++ b/apps/web/src/utils/chains.ts @@ -71,8 +71,11 @@ export const isRouteEnabled = (route: string, chain?: ChainInfo) => { return !featureRoute || hasFeature(chain, featureRoute) } -export const getLatestSafeVersion = (chain: ChainInfo | undefined): SafeVersion => { - const latestSafeVersion = chain?.recommendedMasterCopyVersion || LATEST_SAFE_VERSION +export const getLatestSafeVersion = (chain: ChainInfo | undefined, isUpgrade = false): SafeVersion => { + const latestSafeVersion = isUpgrade + ? chain?.recommendedMasterCopyVersion || LATEST_SAFE_VERSION // for upgrades, use the recommended version + : LATEST_SAFE_VERSION // for Safe creation, always use the latest version + // Without version filter it will always return the LATEST_SAFE_VERSION constant to avoid automatically updating to the newest version if the deployments change const latestDeploymentVersion = (getSafeSingletonDeployment({ network: chain?.chainId, released: true })?.version ?? FALLBACK_SAFE_VERSION) as SafeVersion From 75108d46c6644f1b11cf9223615fa9e0bfe6a0c1 Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:17:52 +0100 Subject: [PATCH 2/2] Fix tests --- apps/web/src/utils/__tests__/chains.test.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/web/src/utils/__tests__/chains.test.ts b/apps/web/src/utils/__tests__/chains.test.ts index 38ec32d031..3f5d16b260 100644 --- a/apps/web/src/utils/__tests__/chains.test.ts +++ b/apps/web/src/utils/__tests__/chains.test.ts @@ -42,17 +42,34 @@ describe('chains', () => { describe('chains', () => { describe('getLatestSafeVersion', () => { it('should return the version from recommendedMasterCopyVersion', () => { + expect( + getLatestSafeVersion( + chainBuilder().with({ chainId: '1', recommendedMasterCopyVersion: '1.4.1' }).build(), + true, + ), + ).toEqual('1.4.1') + expect( + getLatestSafeVersion( + chainBuilder().with({ chainId: '137', recommendedMasterCopyVersion: '1.3.0' }).build(), + true, + ), + ).toEqual('1.3.0') + }) + + it('should always return LATEST_VERSION if true is not passed', () => { expect( getLatestSafeVersion(chainBuilder().with({ chainId: '1', recommendedMasterCopyVersion: '1.4.1' }).build()), ).toEqual('1.4.1') expect( getLatestSafeVersion(chainBuilder().with({ chainId: '137', recommendedMasterCopyVersion: '1.3.0' }).build()), - ).toEqual('1.3.0') + ).toEqual('1.4.1') }) + it('should fall back to LATEST_VERSION', () => { expect( getLatestSafeVersion( chainBuilder().with({ chainId: '11155111', recommendedMasterCopyVersion: null }).build(), + true, ), ).toEqual('1.4.1') })