This repository has been archived by the owner on Nov 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 363
Display readable Safe contract errors #2911
Merged
Merged
Changes from 11 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
5d898f6
feat: Contract error map and extractor
iamacook 6a94c0c
feat: Show contract error notifications
iamacook 1642462
fix: Tests
iamacook 7749fac
chore: Move dispatch + type contractError
iamacook 243a821
Merge branch 'dev' into display-readable-error-codes
iamacook 66ab99d
fix: Set error in catch
iamacook a351f53
Merge branch 'dev' into display-readable-error-codes
iamacook a9a095d
Merge branch 'dev' into display-readable-error-codes
iamacook f4df41f
chore: Refactor + small fixes
iamacook aa4e09d
Merge branch 'dev' into display-readable-error-codes
iamacook 3bcb036
Merge branch 'dev' into display-readable-error-codes
iamacook 8d1c292
fix: Track page w/ search + only decode thrown err
iamacook a041f9f
chore: Decode contract output
iamacook 98a4d8b
Merge branch 'dev' into display-readable-error-codes
iamacook File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { decodeContractError } from '../safeContractErrors' | ||
|
||
describe('decodeContractError', () => { | ||
it('returns safe errors', () => { | ||
expect(decodeContractError('GS000: Could not finish initialization')).toBe('GS000: Could not finish initialization') | ||
}) | ||
|
||
it('returns safe errors irregardless of place in error', () => { | ||
expect(decodeContractError('testGS000test')).toBe('GS000: Could not finish initialization') | ||
expect(decodeContractError('test GS000 test')).toBe('GS000: Could not finish initialization') | ||
}) | ||
it('returns safe errors irregardless of case', () => { | ||
expect(decodeContractError('gs000: testing')).toBe('GS000: Could not finish initialization') | ||
}) | ||
|
||
it('returns provided errors if not safe errors', () => { | ||
expect(decodeContractError('Not a Safe error')).toBe('Not a Safe error') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// https://github.com/gnosis/safe-contracts/blob/main/docs/error_codes.md | ||
export enum CONTRACT_ERRORS { | ||
// General init related | ||
GS000 = 'Could not finish initialization', | ||
GS001 = 'Threshold needs to be defined', | ||
|
||
// General gas/ execution related | ||
GS010 = 'Not enough gas to execute Safe transaction', | ||
GS011 = 'Could not pay gas costs with ether', | ||
GS012 = 'Could not pay gas costs with token', | ||
GS013 = 'Safe transaction failed when gasPrice and safeTxGas were 0', | ||
|
||
// General signature validation related | ||
GS020 = 'Signatures data too short', | ||
GS021 = 'Invalid contract signature location = inside static part', | ||
GS022 = 'Invalid contract signature location = length not present', | ||
GS023 = 'Invalid contract signature location = data not complete', | ||
GS024 = 'Invalid contract signature provided', | ||
GS025 = 'Hash has not been approved', | ||
GS026 = 'Invalid owner provided', | ||
|
||
// General auth related | ||
GS030 = 'Only owners can approve a hash', | ||
GS031 = 'Method can only be called from this contract', | ||
|
||
// Module management related | ||
GS100 = 'Modules have already been initialized', | ||
GS101 = 'Invalid module address provided', | ||
GS102 = 'Module has already been added', | ||
GS103 = 'Invalid prevModule, module pair provided', | ||
GS104 = 'Method can only be called from an enabled module', | ||
|
||
// Owner management related | ||
GS200 = 'Owners have already been setup', | ||
GS201 = 'Threshold cannot exceed owner count', | ||
GS202 = 'Threshold needs to be greater than 0', | ||
GS203 = 'Invalid owner address provided', | ||
GS204 = 'Address is already an owner', | ||
GS205 = 'Invalid prevOwner, owner pair provided', | ||
|
||
// Guard management related | ||
GS300 = 'Guard does not implement IERC165', | ||
} | ||
|
||
export const CONTRACT_ERROR_CODES = Object.keys(CONTRACT_ERRORS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import abi from 'ethereumjs-abi' | ||
|
||
import { CONTRACT_ERRORS, CONTRACT_ERROR_CODES } from 'src/logic/contracts/contracts.d' | ||
import { getWeb3 } from 'src/logic/wallets/getWeb3' | ||
import { GnosisSafe } from 'src/types/contracts/gnosis_safe.d' | ||
|
||
export const decodeContractError = (contractError: string): string => { | ||
const code = CONTRACT_ERROR_CODES.find((code) => { | ||
return contractError.toUpperCase().includes(code.toUpperCase()) | ||
}) | ||
|
||
return code ? `${code}: ${CONTRACT_ERRORS[code]}` : contractError | ||
} | ||
|
||
export const getContractErrorMessage = async ({ | ||
safeInstance, | ||
from, | ||
data, | ||
}: { | ||
safeInstance: GnosisSafe | ||
from: string | ||
data: string | ||
}): Promise<string> => { | ||
const web3 = getWeb3() | ||
|
||
let contractError: string | ||
|
||
try { | ||
const returnData = await web3.eth.call({ | ||
to: safeInstance.options.address, | ||
from, | ||
value: 0, | ||
data, | ||
}) | ||
|
||
const returnBuffer = Buffer.from(returnData.slice(2), 'hex') | ||
contractError = abi.rawDecode(['string'], returnBuffer.slice(4))[0] | ||
} catch (e) { | ||
contractError = e.message | ||
} | ||
|
||
return decodeContractError(contractError) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,7 +47,9 @@ const Routes = (): React.ReactElement => { | |
? location.pathname.replace(getPrefixedSafeAddressSlug(), 'SAFE_ADDRESS') | ||
: location.pathname | ||
trackPage(pathname + location.search) | ||
}, [location, trackPage]) | ||
|
||
// Track when pathname changes | ||
}, [location.pathname, trackPage]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! Please add the search too. |
||
|
||
return ( | ||
<Switch> | ||
|
This file was deleted.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should return null in this case?
And display the original tx err.