diff --git a/apps/contract-verification/src/app/App.css b/apps/contract-verification/src/app/App.css index 0bcd3315a3..f062f4c39a 100644 --- a/apps/contract-verification/src/app/App.css +++ b/apps/contract-verification/src/app/App.css @@ -3,3 +3,4 @@ body { } .fa-arrow-up-right-from-square::before { content: "\f08e"; } +.fa-xmark::before { content: "\f00d"; } diff --git a/apps/contract-verification/src/app/Verifiers/EtherscanVerifier.ts b/apps/contract-verification/src/app/Verifiers/EtherscanVerifier.ts index f3a845fc71..3a6cc3f8f9 100644 --- a/apps/contract-verification/src/app/Verifiers/EtherscanVerifier.ts +++ b/apps/contract-verification/src/app/Verifiers/EtherscanVerifier.ts @@ -75,6 +75,10 @@ export class EtherscanVerifier extends AbstractVerifier { const verificationResponse: EtherscanRpcResponse = await response.json() + if (verificationResponse.result.includes('already verified')) { + return { status: 'already verified', receiptId: null, lookupUrl: this.getContractCodeUrl(submittedContract.address) } + } + if (verificationResponse.status !== '1' || verificationResponse.message !== 'OK') { console.error('Error on Etherscan API verification at ' + this.apiUrl + '\nStatus: ' + verificationResponse.status + '\nMessage: ' + verificationResponse.message + '\nResult: ' + verificationResponse.result) throw new Error(verificationResponse.result) diff --git a/apps/contract-verification/src/app/components/AccordionReceipt.tsx b/apps/contract-verification/src/app/components/AccordionReceipt.tsx index c0e357a6a6..74d339b02b 100644 --- a/apps/contract-verification/src/app/components/AccordionReceipt.tsx +++ b/apps/contract-verification/src/app/components/AccordionReceipt.tsx @@ -2,6 +2,7 @@ import React, { useMemo } from 'react' import { SubmittedContract, VerificationReceipt } from '../types' import { shortenAddress, CustomTooltip } from '@remix-ui/helper' import { AppContext } from '../AppContext' +import { CopyToClipboard } from '@remix-ui/clipboard' interface AccordionReceiptProps { contract: SubmittedContract @@ -13,67 +14,71 @@ export const AccordionReceipt: React.FC = ({ contract, in const [expanded, setExpanded] = React.useState(false) - const chainName = useMemo(() => { - return chains.find((chain) => chain.chainId === parseInt(contract.chainId))?.name ?? 'Unknown Chain' + const chain = useMemo(() => { + return chains.find((c) => c.chainId === parseInt(contract.chainId)) }, [contract, chains]) + const chainName = chain?.name ?? 'Unknown Chain' + + const hasProxy = contract.proxyAddress && contract.proxyReceipts const toggleAccordion = () => { setExpanded(!expanded) } return ( -
-

- -

-
-
-
- Chain ID: - {contract.chainId} -
-
- File: - {contract.filePath} -
-
- Contract: - {contract.contractName} -
-
- Submission: - {new Date(contract.date).toLocaleString()} -
- {!contract.proxyAddress ? ( - - ) : ( - <> -
- - Implementation - - -
-
- - Proxy - {' '} - - {shortenAddress(contract.proxyAddress)} - - -
- - )} + +
+ + + {contract.contractName} at {shortenAddress(contract.address)} {contract.proxyAddress ? 'with proxy' : ''} + +
+ + +
+ +
+
+ Chain: + {chainName} ({contract.chainId}) +
+
+ File: + {contract.filePath} +
+
+ Submitted at: + {new Date(contract.date).toLocaleString()} +
+ +
+ Verified at: + +
+ + {hasProxy && ( + <> +
+ Proxy Address: + + {shortenAddress(contract.proxyAddress)} + + +
+
+ Proxy verified at: + +
+ + )}
) @@ -81,35 +86,20 @@ export const AccordionReceipt: React.FC = ({ contract, in const ReceiptsBody = ({ receipts }: { receipts: VerificationReceipt[] }) => { return ( -
- - - - - - - - - - - - - {receipts.map((receipt) => ( - - - - - - - - - ))} - -
VerifierAPI URLStatusMessageLinkReceiptID
{receipt.verifierInfo.name}{receipt.verifierInfo.apiUrl} - - {receipt.status} - - {receipt.message}{!!receipt.lookupUrl && }{receipt.receiptId}
-
+
    + {receipts.map((receipt) => ( +
  • + + {receipt.verifierInfo.name} + + + + {['verified', 'partially verified', 'already verified'].includes(receipt.status) ? : receipt.status === 'fully verified' ? : receipt.status === 'failed' ? : ['pending', 'awaiting implementation verification'].includes(receipt.status) ? : } + + + {!!receipt.lookupUrl && } +
  • + ))} +
) } diff --git a/apps/contract-verification/src/app/types/VerificationTypes.ts b/apps/contract-verification/src/app/types/VerificationTypes.ts index bfe244a2e1..32c1110a76 100644 --- a/apps/contract-verification/src/app/types/VerificationTypes.ts +++ b/apps/contract-verification/src/app/types/VerificationTypes.ts @@ -57,7 +57,7 @@ export interface SubmittedContracts { type SourcifyStatus = 'fully verified' | 'partially verified' type EtherscanStatus = 'verified' | 'already verified' -export type VerificationStatus = SourcifyStatus | EtherscanStatus | 'failed' | 'pending' | 'not verified' | 'unknown' | 'lookup failed' | 'awaiting implementation verification' +export type VerificationStatus = SourcifyStatus | EtherscanStatus | 'failed' | 'pending' | 'awaiting implementation verification' | 'not verified' | 'lookup failed' | 'unknown' export interface VerificationResponse { status: VerificationStatus diff --git a/apps/contract-verification/src/app/views/ReceiptsView.tsx b/apps/contract-verification/src/app/views/ReceiptsView.tsx index 8b8472d08a..5c7eb7b1fa 100644 --- a/apps/contract-verification/src/app/views/ReceiptsView.tsx +++ b/apps/contract-verification/src/app/views/ReceiptsView.tsx @@ -7,8 +7,10 @@ export const ReceiptsView = () => { const contracts = Object.values(submittedContracts).reverse() return ( -
- {contracts.length > 0 ? contracts.map((contract, index) => ) :
No contracts submitted for verification
} +
+ {contracts.length > 0 ? contracts.map((contract, index) => ( + + )) :
No contracts submitted for verification
}
) }