From 4e7d01d95115edf4bd9202a1a4f96d344a3115a4 Mon Sep 17 00:00:00 2001 From: iamacook Date: Wed, 25 Jan 2023 13:54:30 +0100 Subject: [PATCH] fix: Safe version feature helper --- packages/safe-core-sdk/src/Safe.ts | 4 +- .../src/managers/fallbackHandlerManager.ts | 4 +- .../src/managers/guardManager.ts | 4 +- .../safe-core-sdk/src/utils/safeVersions.ts | 37 ++++++++----------- .../src/utils/transactions/utils.ts | 7 +++- 5 files changed, 26 insertions(+), 30 deletions(-) diff --git a/packages/safe-core-sdk/src/Safe.ts b/packages/safe-core-sdk/src/Safe.ts index 827a65ee8..cd24e85b8 100644 --- a/packages/safe-core-sdk/src/Safe.ts +++ b/packages/safe-core-sdk/src/Safe.ts @@ -31,7 +31,7 @@ import { standardizeMetaTransactionData, standardizeSafeTransactionData } from './utils/transactions/utils' -import { FEATURES, hasFeature } from './utils/safeVersions' +import { SAFE_FEATURES, hasSafeFeature } from './utils/safeVersions' export interface SafeConfig { /** ethAdapter - Ethereum adapter */ @@ -470,7 +470,7 @@ class Safe { signature = await this.signTypedData(transaction) } else { const safeVersion = await this.getContractVersion() - if (!hasFeature(FEATURES.ETH_SIGN, safeVersion)) { + if (!hasSafeFeature(SAFE_FEATURES.ETH_SIGN, safeVersion)) { throw new Error('eth_sign is only supported by Safes >= v1.1.0') } const txHash = await this.getTransactionHash(transaction) diff --git a/packages/safe-core-sdk/src/managers/fallbackHandlerManager.ts b/packages/safe-core-sdk/src/managers/fallbackHandlerManager.ts index 5cce65755..d4a147e14 100644 --- a/packages/safe-core-sdk/src/managers/fallbackHandlerManager.ts +++ b/packages/safe-core-sdk/src/managers/fallbackHandlerManager.ts @@ -1,7 +1,7 @@ import { EthAdapter, GnosisSafeContract } from '@safe-global/safe-core-sdk-types' import { isZeroAddress, sameString } from '../utils' import { ZERO_ADDRESS } from '../utils/constants' -import { FEATURES, hasFeature } from '../utils/safeVersions' +import { SAFE_FEATURES, hasSafeFeature } from '../utils/safeVersions' class FallbackHandlerManager { #ethAdapter: EthAdapter @@ -38,7 +38,7 @@ class FallbackHandlerManager { async getFallbackHandler(): Promise { const safeVersion = await this.#safeContract.getVersion() - if (hasFeature(FEATURES.SAFE_FALLBACK_HANDLER, safeVersion)) { + if (hasSafeFeature(SAFE_FEATURES.SAFE_FALLBACK_HANDLER, safeVersion)) { return this.#ethAdapter.getStorageAt(this.#safeContract.getAddress(), this.#slot) } else { throw new Error( diff --git a/packages/safe-core-sdk/src/managers/guardManager.ts b/packages/safe-core-sdk/src/managers/guardManager.ts index fe285fa42..1e5d64a56 100644 --- a/packages/safe-core-sdk/src/managers/guardManager.ts +++ b/packages/safe-core-sdk/src/managers/guardManager.ts @@ -1,7 +1,7 @@ import { EthAdapter, GnosisSafeContract } from '@safe-global/safe-core-sdk-types' import { isZeroAddress, sameString } from '../utils' import { ZERO_ADDRESS } from '../utils/constants' -import { FEATURES, hasFeature } from '../utils/safeVersions' +import { SAFE_FEATURES, hasSafeFeature } from '../utils/safeVersions' class GuardManager { #ethAdapter: EthAdapter @@ -35,7 +35,7 @@ class GuardManager { async getGuard(): Promise { const safeVersion = await this.#safeContract.getVersion() - if (hasFeature(FEATURES.SAFE_TX_GUARDS, safeVersion)) { + if (hasSafeFeature(SAFE_FEATURES.SAFE_TX_GUARDS, safeVersion)) { return this.#ethAdapter.getStorageAt(this.#safeContract.getAddress(), this.#slot) } else { throw new Error( diff --git a/packages/safe-core-sdk/src/utils/safeVersions.ts b/packages/safe-core-sdk/src/utils/safeVersions.ts index dfe07a2a8..5a71044c1 100644 --- a/packages/safe-core-sdk/src/utils/safeVersions.ts +++ b/packages/safe-core-sdk/src/utils/safeVersions.ts @@ -1,31 +1,24 @@ import semverSatisfies from 'semver/functions/satisfies' -export enum FEATURES { - SAFE_TX_GAS_OPTIONAL, - SAFE_TX_GUARDS, - SAFE_FALLBACK_HANDLER, - ETH_SIGN +export enum SAFE_FEATURES { + SAFE_TX_GAS_OPTIONAL = 'SAFE_TX_GAS_OPTIONAL', + SAFE_TX_GUARDS = 'SAFE_TX_GUARDS', + SAFE_FALLBACK_HANDLER = 'SAFE_FALLBACK_HANDLER', + ETH_SIGN = 'ETH_SIGN' } -const FEATURES_BY_VERSION: Record = { - [FEATURES.SAFE_TX_GAS_OPTIONAL]: '>=1.3.0', - [FEATURES.SAFE_TX_GUARDS]: '>=1.3.0', - [FEATURES.SAFE_FALLBACK_HANDLER]: '>=1.1.1', - [FEATURES.ETH_SIGN]: '>=1.1.0' +const SAFE_FEATURES_BY_VERSION: Record = { + [SAFE_FEATURES.SAFE_TX_GAS_OPTIONAL]: '>=1.3.0', + [SAFE_FEATURES.SAFE_TX_GUARDS]: '>=1.3.0', + [SAFE_FEATURES.SAFE_FALLBACK_HANDLER]: '>=1.1.1', + [SAFE_FEATURES.ETH_SIGN]: '>=1.1.0' } -const isEnabledByVersion = (feature: FEATURES, version: string): boolean => { - if (!(feature in FEATURES_BY_VERSION)) { - return true +// Note: gatewau returns `SafeInfo['version']` as `null` for unsupported contracts +export const hasSafeFeature = (feature: SAFE_FEATURES, version: string | null): boolean => { + if (!version || !(feature in SAFE_FEATURES_BY_VERSION)) { + return false } - return semverSatisfies(version, FEATURES_BY_VERSION[feature]) -} - -export const enabledFeatures = (version: string): FEATURES[] => { - const features = Object.values(FEATURES) as FEATURES[] - return features.filter((feature) => isEnabledByVersion(feature, version)) -} -export const hasFeature = (name: FEATURES, version: string): boolean => { - return enabledFeatures(version).includes(name) + return semverSatisfies(version, SAFE_FEATURES_BY_VERSION[feature]) } diff --git a/packages/safe-core-sdk/src/utils/transactions/utils.ts b/packages/safe-core-sdk/src/utils/transactions/utils.ts index 48e39b913..4dc75e00f 100644 --- a/packages/safe-core-sdk/src/utils/transactions/utils.ts +++ b/packages/safe-core-sdk/src/utils/transactions/utils.ts @@ -9,7 +9,7 @@ import { SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' import { ZERO_ADDRESS } from '../constants' -import { FEATURES, hasFeature } from '../safeVersions' +import { SAFE_FEATURES, hasSafeFeature } from '../safeVersions' import { estimateTxGas } from './gas' export function standardizeMetaTransactionData( @@ -47,7 +47,10 @@ export async function standardizeSafeTransactionData( } } const safeVersion = await safeContract.getVersion() - if (hasFeature(FEATURES.SAFE_TX_GAS_OPTIONAL, safeVersion) && standardizedTxs.gasPrice === 0) { + if ( + hasSafeFeature(SAFE_FEATURES.SAFE_TX_GAS_OPTIONAL, safeVersion) && + standardizedTxs.gasPrice === 0 + ) { safeTxGas = 0 } else { safeTxGas = await estimateTxGas(