From 2e850e668971a802d229d4675abb450e7a94393e Mon Sep 17 00:00:00 2001 From: Uxio Fuentefria Date: Mon, 21 Oct 2019 16:40:11 +0200 Subject: [PATCH] Support Safes with old proxy (payingProxy) - Version of the Safe has to be at least v1.0.0 - Closes #213 --- src/logic/contracts/safeContracts.js | 25 +++++++++++++++++++ .../load/components/DetailsForm/index.jsx | 14 +++-------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/logic/contracts/safeContracts.js b/src/logic/contracts/safeContracts.js index 30a005ed..9f8e039a 100644 --- a/src/logic/contracts/safeContracts.js +++ b/src/logic/contracts/safeContracts.js @@ -2,6 +2,7 @@ import contract from 'truffle-contract' import ProxyFactorySol from '@gnosis.pm/safe-contracts/build/contracts/ProxyFactory.json' import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json' +import SafeProxy from '@gnosis.pm/safe-contracts/build/contracts/Proxy.json' import { ensureOnce } from '~/utils/singleton' import { getWeb3 } from '~/logic/wallets/getWeb3' import { calculateGasOf, calculateGasPrice } from '~/logic/wallets/ethTransactions' @@ -99,3 +100,27 @@ export const getGnosisSafeInstanceAt = async (safeAddress: string) => { return gnosisSafe } + +const cleanByteCodeMetadata = (bytecode: string): string => { + const metaData = 'a165' + return bytecode.substring(0, bytecode.lastIndexOf(metaData)) +} + +export const validateProxy = async (safeAddress: string): boolean => { + // https://solidity.readthedocs.io/en/latest/metadata.html#usage-for-source-code-verification + const web3 = getWeb3() + const code = await web3.eth.getCode(safeAddress) + const codeWithoutMetadata = cleanByteCodeMetadata(code) + const supportedProxies = [SafeProxy] + for (let i = 0; i < supportedProxies.length; i += 1) { + const proxy = supportedProxies[i] + const proxyCode = proxy.deployedBytecode + const proxyCodeWithoutMetadata = cleanByteCodeMetadata(proxyCode) + if (codeWithoutMetadata === proxyCodeWithoutMetadata) { + return true + } + } + // Old PayingProxyCode + const oldProxyCode = '0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600' + return codeWithoutMetadata === oldProxyCode +} diff --git a/src/routes/load/components/DetailsForm/index.jsx b/src/routes/load/components/DetailsForm/index.jsx index da0f8fd3..8c0d2374 100644 --- a/src/routes/load/components/DetailsForm/index.jsx +++ b/src/routes/load/components/DetailsForm/index.jsx @@ -1,7 +1,6 @@ // @flow import * as React from 'react' import { withStyles } from '@material-ui/core/styles' -import SafeProxy from '@gnosis.pm/safe-contracts/build/contracts/Proxy.json' import InputAdornment from '@material-ui/core/InputAdornment' import CheckCircle from '@material-ui/icons/CheckCircle' import Field from '~/components/forms/Field' @@ -15,7 +14,7 @@ import Paragraph from '~/components/layout/Paragraph' import OpenPaper from '~/components/Stepper/OpenPaper' import { FIELD_LOAD_NAME, FIELD_LOAD_ADDRESS } from '~/routes/load/components/fields' import { getWeb3 } from '~/logic/wallets/getWeb3' -import { getSafeMasterContract } from '~/logic/contracts/safeContracts' +import { getSafeMasterContract, validateProxy } from '~/logic/contracts/safeContracts' import { secondary } from '~/theme/variables' type Props = { @@ -56,15 +55,8 @@ export const safeFieldsValidation = async (values: Object) => { return errors } - // https://solidity.readthedocs.io/en/latest/metadata.html#usage-for-source-code-verification - const metaData = 'a165' - - const code = await web3.eth.getCode(safeAddress) - const codeWithoutMetadata = code.substring(0, code.lastIndexOf(metaData)) - const proxyCode = SafeProxy.deployedBytecode - const proxyCodeWithoutMetadata = proxyCode.substring(0, proxyCode.lastIndexOf(metaData)) - const safeInstance = codeWithoutMetadata === proxyCodeWithoutMetadata - if (!safeInstance) { + const isValidProxy = await validateProxy(safeAddress) + if (!isValidProxy) { errors[FIELD_LOAD_ADDRESS] = SAFE_INSTANCE_ERROR return errors }