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: handle nullable SafeInfo['version'] #1340

Merged
merged 5 commits into from
Dec 13, 2022
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@reduxjs/toolkit": "^1.8.2",
"@safe-global/safe-core-sdk": "^3.2.0",
"@safe-global/safe-ethers-lib": "^1.7.0",
"@safe-global/safe-gateway-typescript-sdk": "^3.5.3",
"@safe-global/safe-gateway-typescript-sdk": "^3.5.4",
"@sentry/react": "^7.8.1",
"@sentry/tracing": "^7.8.1",
"@truffle/hdwallet-provider": "^2.0.14",
Expand Down
14 changes: 10 additions & 4 deletions src/components/settings/ContractVersion/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,16 @@ export const ContractVersion = ({ isGranted }: { isGranted: boolean }) => {
<Typography variant="h4" fontWeight={700} marginBottom={1}>
Contract version
</Typography>
<ExternalLink href={safeMasterCopy?.deployerRepoUrl}>
{safe.version}
{getSafeVersionUpdate()}
</ExternalLink>
{safe.version ? (
<ExternalLink href={safeMasterCopy?.deployerRepoUrl}>
{safe.version}
{getSafeVersionUpdate()}
</ExternalLink>
) : (
<Typography variant="body1" fontWeight={400}>
Unsupported contract
</Typography>
)}

{showUpdateDialog && isGranted && <UpdateSafeDialog />}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/settings/TransactionGuards/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const GUARD_SUPPORTED_SAFE_VERSION = '1.3.0'
const TransactionGuards = () => {
const { safe, safeLoaded } = useSafeInfo()

const isVersionWithGuards = safeLoaded && gte(safe.version, GUARD_SUPPORTED_SAFE_VERSION)
const isVersionWithGuards = safeLoaded && safe.version && gte(safe.version, GUARD_SUPPORTED_SAFE_VERSION)

if (!isVersionWithGuards) {
return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ const ReviewBatchExecute = ({ data, onSubmit }: { data: BatchExecuteData; onSubm
}, [data.txs, chain?.chainId])

const multiSendContract = useMemo(() => {
if (!chain?.chainId) return
if (!chain?.chainId || !safe.version) return
return getMultiSendCallOnlyContractInstance(chain.chainId, safe.version)
}, [chain?.chainId, safe.version])

const multiSendTxs = useMemo(() => {
if (!txsWithDetails || !chain) return
if (!txsWithDetails || !chain || !safe.version) return
return getMultiSendTxs(txsWithDetails, chain, safe.address.value, safe.version)
}, [chain, safe.address.value, safe.version, txsWithDetails])

Expand Down
9 changes: 8 additions & 1 deletion src/hooks/coreSDK/safeCoreSDK.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import chains from '@/config/chains'
import { getWeb3 } from '@/hooks/wallets/web3'
import ExternalStore from '@/services/ExternalStore'
import { invariant } from '@/utils/helpers'
import { Web3Provider } from '@ethersproject/providers'
import Safe from '@safe-global/safe-core-sdk'
import type { SafeVersion } from '@safe-global/safe-core-sdk-types'
import EthersAdapter from '@safe-global/safe-ethers-lib'
import type { SafeInfo } from '@safe-global/safe-gateway-typescript-sdk'
import { type EIP1193Provider } from '@web3-onboard/core'
import { ethers } from 'ethers'
import semverSatisfies from 'semver/functions/satisfies'
Expand All @@ -14,11 +16,16 @@ export const isLegacyVersion = (safeVersion: string): boolean => {
return semverSatisfies(safeVersion, LEGACY_VERSION)
}

export const isValidSafeVersion = (safeVersion?: string): safeVersion is SafeVersion => {
export const isValidSafeVersion = (safeVersion?: SafeInfo['version']): safeVersion is SafeVersion => {
const SAFE_VERSIONS: SafeVersion[] = ['1.3.0', '1.2.0', '1.1.1']
return !!safeVersion && SAFE_VERSIONS.some((version) => semverSatisfies(safeVersion, version))
}

// `assert` does not work with arrow functions
export function assertValidSafeVersion<T extends SafeInfo['version']>(safeVersion?: T): asserts safeVersion {
return invariant(isValidSafeVersion(safeVersion), `${safeVersion} is not a valid Safe version`)
}

export const createEthersAdapter = (provider = getWeb3()) => {
if (!provider) {
throw new Error('Unable to create `EthersAdapter` without a provider')
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/coreSDK/useInitSafeCoreSDK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const useInitSafeCoreSDK = () => {
const dispatch = useAppDispatch()

useEffect(() => {
if (!safeLoaded || !wallet?.provider || safe.chainId !== wallet.chainId) {
if (!safeLoaded || !wallet?.provider || safe.chainId !== wallet.chainId || !safe.version) {
// If we don't reset the SDK, a previous Safe could remain in the store
setSafeSDK(undefined)
return
Expand Down
13 changes: 7 additions & 6 deletions src/services/contracts/safeContracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { SafeInfo } from '@safe-global/safe-gateway-typescript-sdk'
import { getMasterCopies, type ChainInfo } from '@safe-global/safe-gateway-typescript-sdk'
import type { GetContractProps, SafeVersion } from '@safe-global/safe-core-sdk-types'
import { type Sign_message_lib } from '@/types/contracts/Sign_message_lib'
import { createEthersAdapter, isValidSafeVersion } from '@/hooks/coreSDK/safeCoreSDK'
import { assertValidSafeVersion, createEthersAdapter } from '@/hooks/coreSDK/safeCoreSDK'
import { sameAddress } from '@/utils/addresses'
import type CompatibilityFallbackHandlerEthersContract from '@safe-global/safe-ethers-lib/dist/src/contracts/CompatibilityFallbackHandler/CompatibilityFallbackHandlerEthersContract'

Expand All @@ -27,11 +27,9 @@ export const isValidMasterCopy = async (chainId: string, address: string): Promi

export const _getValidatedGetContractProps = (
chainId: string,
safeVersion: string,
safeVersion: SafeInfo['version'],
): Pick<GetContractProps, 'chainId' | 'safeVersion'> => {
if (!isValidSafeVersion(safeVersion)) {
throw new Error(`${safeVersion} is not a valid Safe version`)
}
assertValidSafeVersion(safeVersion)

// SDK request here: https://github.com/safe-global/safe-core-sdk/issues/261
// Remove '+L2'/'+Circles' metadata from version
Expand Down Expand Up @@ -125,7 +123,10 @@ export const getMultiSendCallOnlyContractAddress = (chainId: string): string | u
return deployment?.networkAddresses[chainId]
}

export const getMultiSendCallOnlyContractInstance = (chainId: string, safeVersion: string = LATEST_SAFE_VERSION) => {
export const getMultiSendCallOnlyContractInstance = (
chainId: string,
safeVersion: SafeInfo['version'] = LATEST_SAFE_VERSION,
) => {
const ethAdapter = createEthersAdapter()

return ethAdapter.getMultiSendCallOnlyContract({
Expand Down
3 changes: 3 additions & 0 deletions src/services/tx/safeUpdateParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { OperationType } from '@safe-global/safe-core-sdk-types'
import type { ChainInfo, SafeInfo } from '@safe-global/safe-gateway-typescript-sdk'
import { getFallbackHandlerContractInstance, getGnosisSafeContractInstance } from '@/services/contracts/safeContracts'
import { LATEST_SAFE_VERSION } from '@/config/constants'
import { assertValidSafeVersion } from '@/hooks/coreSDK/safeCoreSDK'

// TODO: Check if these are still needed
export const CHANGE_MASTER_COPY_ABI = 'function changeMasterCopy(address _masterCopy)'
Expand All @@ -15,6 +16,8 @@ export const CHANGE_FALLBACK_HANDLER_ABI = 'function setFallbackHandler(address
* Only works for safes < 1.3.0 as the changeMasterCopy function was removed
*/
export const createUpdateSafeTxs = (safe: SafeInfo, chain: ChainInfo): MetaTransactionData[] => {
assertValidSafeVersion(safe.version)

const latestMasterCopy = getGnosisSafeContractInstance(chain, LATEST_SAFE_VERSION)
const safeContractInstance = getGnosisSafeContractInstance(chain, safe.version)

Expand Down
8 changes: 8 additions & 0 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// `assert` does not work with arrow functions
export function invariant<T extends unknown>(condition: T, error: string): asserts condition {
if (condition) {
return
}

throw new Error(error)
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3275,10 +3275,10 @@
"@safe-global/safe-core-sdk-utils" "^1.5.0"
ethers "^5.7.2"

"@safe-global/safe-gateway-typescript-sdk@^3.5.3":
version "3.5.3"
resolved "https://registry.yarnpkg.com/@safe-global/safe-gateway-typescript-sdk/-/safe-gateway-typescript-sdk-3.5.3.tgz#07b5307601ba9d9d0d62f6366fdfc3cdfdfc6f87"
integrity sha512-HzvCmFHw9NEOJK9d3X8nqG3MMuw+/ceccltrgBenHn8OUxNkv8za9jUou0YUmG0HtJ4tKFTW+z8AwpohHTmWAw==
"@safe-global/safe-gateway-typescript-sdk@^3.5.4":
version "3.5.4"
resolved "https://registry.yarnpkg.com/@safe-global/safe-gateway-typescript-sdk/-/safe-gateway-typescript-sdk-3.5.4.tgz#daa13d830eb8b6c8f60bf4026be42a9965abcc35"
integrity sha512-olTC+2lxb45MyG5Rxgs0UO1gd3MKYW8ahTvY88nV64KMEbjQQUl0lbQ8VlVT7BZsWuVgG7HshrPDsKU/wPVTeA==
dependencies:
cross-fetch "^3.1.5"

Expand Down