Skip to content

Commit

Permalink
fix: Safe version feature helper
Browse files Browse the repository at this point in the history
  • Loading branch information
iamacook committed Jan 25, 2023
1 parent 1f77a6f commit 4e7d01d
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 30 deletions.
4 changes: 2 additions & 2 deletions packages/safe-core-sdk/src/Safe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions packages/safe-core-sdk/src/managers/fallbackHandlerManager.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -38,7 +38,7 @@ class FallbackHandlerManager {

async getFallbackHandler(): Promise<string> {
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(
Expand Down
4 changes: 2 additions & 2 deletions packages/safe-core-sdk/src/managers/guardManager.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -35,7 +35,7 @@ class GuardManager {

async getGuard(): Promise<string> {
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(
Expand Down
37 changes: 15 additions & 22 deletions packages/safe-core-sdk/src/utils/safeVersions.ts
Original file line number Diff line number Diff line change
@@ -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<string, string> = {
[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, string> = {
[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])
}
7 changes: 5 additions & 2 deletions packages/safe-core-sdk/src/utils/transactions/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit 4e7d01d

Please sign in to comment.