diff --git a/libs/remix-core-plugin/src/types/contract.ts b/libs/remix-core-plugin/src/types/contract.ts index 98beee2e68..cccce84203 100644 --- a/libs/remix-core-plugin/src/types/contract.ts +++ b/libs/remix-core-plugin/src/types/contract.ts @@ -10,7 +10,6 @@ export interface FuncABI { export interface ContractData { name: string, - contractName?: string, contract: any, compiler: any, abi: FuncABI[], diff --git a/libs/remix-ui/run-tab/src/lib/actions/deploy.ts b/libs/remix-ui/run-tab/src/lib/actions/deploy.ts index 8dc80b3e80..91e476e08f 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/deploy.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/deploy.ts @@ -381,15 +381,14 @@ export const isValidContractUpgrade = async (plugin: RunTab, dispatch: React.Dis const newImpl = new UpgradeableContract(newContractName, solcInput, solcOutput, { kind: 'uups' }) const report = oldImpl.getStorageUpgradeReport(newImpl, { kind: 'uups' }) - console.log('report: ', report) return report } else { - return { success: false, error: 'Previous contract implementation not available for upgrade comparison.' } + return { ok: false, pass: false, warning: 'Previous contract implementation not available for upgrade comparison.' } } } else { - return { success: false, error: 'Previous contract implementation not available for upgrade comparison.' } + return { ok: false, pass: false, warning: 'Previous contract implementation not available for upgrade comparison.' } } } else { - return { success: false, error: 'Previous contract implementation not available for upgrade comparison.' } + return { ok: false, pass: false, warning: 'Previous contract implementation not available for upgrade comparison.' } } } diff --git a/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx b/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx index 91479413f7..83fa37faea 100644 --- a/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx @@ -235,7 +235,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) { } const isValidProxyUpgrade = (proxyAddress: string) => { - props.isValidProxyUpgrade(proxyAddress, loadedContractData.contractName, loadedContractData.compiler.source, loadedContractData.compiler.data) + return props.isValidProxyUpgrade(proxyAddress, loadedContractData.name, loadedContractData.compiler.source, loadedContractData.compiler.data) } const checkSumWarning = () => { @@ -318,6 +318,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) { proxy={props.proxy} isValidProxyAddress={props.isValidProxyAddress} isValidProxyUpgrade={isValidProxyUpgrade} + modal={props.modal} />
{ + const handleActionClick = async () => { if (deployState.deploy) { const proxyInitializeString = getMultiValsString(initializeFields.current) props.clickCallBack(props.initializerOptions.inputs.inputs, proxyInitializeString, ['Deploy with Proxy']) } else if (deployState.upgrade) { - props.isValidProxyUpgrade(proxyAddress) - !proxyAddressError && props.clickCallBack(props.funcABI.inputs, proxyAddress, ['Upgrade with Proxy']) + if (proxyAddress === '') { + setProxyAddressError('proxy address cannot be empty') + } else { + const isValidProxyAddress = await props.isValidProxyAddress(proxyAddress) + + if (isValidProxyAddress) { + setProxyAddressError('') + const upgradeReport: any = await props.isValidProxyUpgrade(proxyAddress) + + if (upgradeReport.ok) { + !proxyAddressError && props.clickCallBack(props.funcABI.inputs, proxyAddress, ['Upgrade with Proxy']) + } else { + if (upgradeReport.warning) { + props.modal('Warning', upgradeReport.warning, 'Proceed', () => { + !proxyAddressError && props.clickCallBack(props.funcABI.inputs, proxyAddress, ['Upgrade with Proxy']) + }, 'Cancel', () => {}) + } else { + props.modal('Proxy Upgrade Error', `New deployment storage layout is incompactible with previous deployment.\n + ${upgradeReport.ops.map((failedCase) => `"${failedCase.kind}": ${failedCase.original.label}`).join('\n')}\n + Do you want to continue?`, 'Proceed', () => { + !proxyAddressError && props.clickCallBack(props.funcABI.inputs, proxyAddress, ['Upgrade with Proxy']) + }, 'Cancel', () => {}) + } + // console.log('upgradeReport: ', upgradeReport) + } + } else { + setProxyAddressError('not a valid contract address') + } + } } else { props.clickCallBack(props.funcABI.inputs, basicInput) } @@ -233,18 +260,6 @@ export function ContractGUI (props: ContractGUIProps) { setProxyAddress(address) } - const validateProxyAddress = async (address: string) => { - if (address === '') { - setProxyAddressError('proxy address cannot be empty') - } else { - if (await props.isValidProxyAddress(address)) { - setProxyAddressError('') - } else { - setProxyAddressError('not a valid contract address') - } - } - } - const toggleDropdown = (isOpen: boolean) => { setShowDropdown(isOpen) } diff --git a/libs/remix-ui/run-tab/src/lib/types/index.ts b/libs/remix-ui/run-tab/src/lib/types/index.ts index 2d17006664..87cbe50b43 100644 --- a/libs/remix-ui/run-tab/src/lib/types/index.ts +++ b/libs/remix-ui/run-tab/src/lib/types/index.ts @@ -3,6 +3,7 @@ import { CompilerAbstract } from '@remix-project/remix-solidity' import { ContractData, FuncABI } from '@remix-project/core-plugin' import { RunTab } from './run-tab' import { SolcInput, SolcOutput } from '@openzeppelin/upgrades-core' +import { LayoutCompatibilityReport } from '@openzeppelin/upgrades-core/dist/storage/report' export interface RunTabProps { plugin: RunTab } @@ -264,7 +265,7 @@ export interface ContractDropdownProps { setSelectedContract: (contractName: string) => void remixdActivated: boolean, isValidProxyAddress?: (address: string) => Promise, - isValidProxyUpgrade?: (proxyAddress: string, contractName: string, solcInput: SolcInput, solcOuput: SolcOutput) => void, + isValidProxyUpgrade?: (proxyAddress: string, contractName: string, solcInput: SolcInput, solcOuput: SolcOutput) => Promise, proxy: { deployments: { address: string, date: string, contractName: string }[] } } @@ -362,7 +363,8 @@ export interface ContractGUIProps { initializerOptions?: DeployOption, proxy?: { deployments: { address: string, date: string, contractName: string }[] }, isValidProxyAddress?: (address: string) => Promise, - isValidProxyUpgrade?: (proxyAddress: string) => void + isValidProxyUpgrade?: (proxyAddress: string) => Promise, + modal?: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void } export interface MainnetProps { network: Network,