diff --git a/apps/remix-ide/src/app/components/preload.tsx b/apps/remix-ide/src/app/components/preload.tsx index 6674b1bcfd..f607264d63 100644 --- a/apps/remix-ide/src/app/components/preload.tsx +++ b/apps/remix-ide/src/app/components/preload.tsx @@ -35,7 +35,7 @@ export const Preload = () => { }) }).catch(err => { _paq.push(['trackEvent', 'Preload', 'error', err && err.message]) - console.log('Error loading Remix:', err) + console.error('Error loading Remix:', err) setError(true) }) } diff --git a/libs/remix-core-plugin/src/types/contract.ts b/libs/remix-core-plugin/src/types/contract.ts index aaa6bb4b14..f0a9e9f60f 100644 --- a/libs/remix-core-plugin/src/types/contract.ts +++ b/libs/remix-core-plugin/src/types/contract.ts @@ -9,6 +9,7 @@ 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/actions.ts b/libs/remix-ui/run-tab/src/lib/actions/actions.ts index 09302b7284..0d12cbb4e1 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/actions.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/actions.ts @@ -92,6 +92,5 @@ export const setSendTransactionValue = (dispatch: React.Dispatch, value: st } export const addNewProxyDeployment = (dispatch: React.Dispatch, address: string, date: Date) => { - console.log('called deployement: ', address, date) dispatch(newProxyDeployment({ address, date })) } \ No newline at end of file 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 10428ced99..21a881b32a 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/deploy.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/deploy.ts @@ -2,7 +2,9 @@ import { ContractData, FuncABI, NetworkDeploymentFile } from "@remix-project/cor import { RunTab } from "../types/run-tab" import { CompilerAbstract as CompilerAbstractType } from '@remix-project/remix-solidity' import * as remixLib from '@remix-project/remix-lib' -import { UpgradeableContract } from '@openzeppelin/upgrades-core' +import { SolcInput, SolcOutput } from "@openzeppelin/upgrades-core" +// Used direct path to UpgradeableContract class to fix cyclic dependency error from @openzeppelin/upgrades-core library +import { UpgradeableContract } from '../../../../../../node_modules/@openzeppelin/upgrades-core/dist/standalone' import { DeployMode, MainnetPrompt } from "../types" import { displayNotification, displayPopUp, fetchProxyDeploymentsSuccess, setDecodedResponse } from "./payload" import { addInstance } from "./actions" @@ -357,7 +359,7 @@ export const getNetworkProxyAddresses = async (plugin: RunTab, dispatch: React.D } } -export const isValidContractUpgrade = async (plugin: RunTab, dispatch: React.Dispatch, proxyAddress: string) => { +export const isValidContractUpgrade = async (plugin: RunTab, dispatch: React.Dispatch, proxyAddress: string, newContractName: string, solcInput: SolcInput, solcOutput: SolcOutput) => { // build current contract first to get artefacts. const network = plugin.blockchain.networkStatus.network const identifier = network.name === 'custom' ? network.name + '-' + network.id : network.name @@ -368,9 +370,18 @@ export const isValidContractUpgrade = async (plugin: RunTab, dispatch: React.Dis const parsedNetworkFile: NetworkDeploymentFile = JSON.parse(networkFile) if (parsedNetworkFile.deployments[proxyAddress] && parsedNetworkFile.deployments[proxyAddress].solcInput) { - const oldImpl = new UpgradeableContract(parsedNetworkFile.deployments[proxyAddress].contractName, parsedNetworkFile.deployments[proxyAddress].solcInput, parsedNetworkFile.deployments[proxyAddress].solcOutput) + try { + const oldImpl = new UpgradeableContract(parsedNetworkFile.deployments[proxyAddress].contractName, parsedNetworkFile.deployments[proxyAddress].solcInput, parsedNetworkFile.deployments[proxyAddress].solcOutput, { kind: 'uups' }) + const newImpl = new UpgradeableContract(newContractName, solcInput, solcOutput, { kind: 'uups' }) + const report = oldImpl.getStorageUpgradeReport(newImpl, { kind: 'uups' }) + + + console.log('report: ', report) + } catch (e) { + console.log('e: ', e) + return { success: false, error: 'Previous contract implementation not available for upgrade comparison.' } + } - console.log('oldImpl: ', oldImpl) } else { return { success: false, error: 'Previous contract implementation not available for upgrade comparison.' } } diff --git a/libs/remix-ui/run-tab/src/lib/actions/index.ts b/libs/remix-ui/run-tab/src/lib/actions/index.ts index 6fd0182d8e..e4d22c7e71 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/index.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/index.ts @@ -6,11 +6,12 @@ import { createNewBlockchainAccount, fillAccountsList, setExecutionContext, sign import { clearInstances, clearPopUp, removeInstance, setAccount, setGasFee, setMatchPassphrasePrompt, setNetworkNameFromProvider, setPassphrasePrompt, setSelectedContract, setSendTransactionValue, setUnit, updateBaseFeePerGas, updateConfirmSettings, updateGasPrice, updateGasPriceStatus, updateMaxFee, updateMaxPriorityFee, updateScenarioPath } from './actions' -import { createInstance, getContext, getFuncABIInputs, getSelectedContract, loadAddress, runTransactions, updateInstanceBalance, syncContractsInternal, isValidContractAddress } from './deploy' +import { createInstance, getContext, getFuncABIInputs, getSelectedContract, loadAddress, runTransactions, updateInstanceBalance, syncContractsInternal, isValidContractAddress, isValidContractUpgrade } from './deploy' import { CompilerAbstract as CompilerAbstractType } from '@remix-project/remix-solidity' import { ContractData, FuncABI } from "@remix-project/core-plugin" import { DeployMode, MainnetPrompt } from '../types' import { runCurrentScenario, storeScenario } from './recorder' +import { SolcInput, SolcOutput } from '@openzeppelin/upgrades-core' declare global { interface Window { @@ -62,4 +63,5 @@ export const getFuncABIValues = (funcABI: FuncABI) => getFuncABIInputs(plugin, f export const setNetworkName = (networkName: string) => setNetworkNameFromProvider(dispatch, networkName) export const updateSelectedContract = (contractName) => setSelectedContract(dispatch, contractName) export const syncContracts = () => syncContractsInternal(plugin) -export const isValidProxyAddress = (address: string) => isValidContractAddress(plugin, address) \ No newline at end of file +export const isValidProxyAddress = (address: string) => isValidContractAddress(plugin, address) +export const isValidProxyUpgrade = (proxyAddress: string, contractName: string, solcInput: SolcInput, solcOuput: SolcOutput) => isValidContractUpgrade(plugin, dispatch, proxyAddress, contractName, solcInput, solcOuput) \ No newline at end of file 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 7e11803b0c..91479413f7 100644 --- a/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx @@ -234,6 +234,10 @@ export function ContractDropdownUI (props: ContractDropdownProps) { props.setSelectedContract(value) } + const isValidProxyUpgrade = (proxyAddress: string) => { + props.isValidProxyUpgrade(proxyAddress, loadedContractData.contractName, loadedContractData.compiler.source, loadedContractData.compiler.data) + } + const checkSumWarning = () => { return ( @@ -313,6 +317,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) { lookupOnly={false} proxy={props.proxy} isValidProxyAddress={props.isValidProxyAddress} + isValidProxyUpgrade={isValidProxyUpgrade} />
(false) const [toggleUpgradeImp, setToggleUpgradeImp] = useState(false) const [deployState, setDeployState] = useState<{ deploy: boolean, upgrade: boolean }>({ deploy: false, upgrade: false }) - const [useLastProxy, setUseLastProxy] = useState(false) const [proxyAddress, setProxyAddress] = useState('') - const [selectedProxyAddress, setSelectedProxyAddress] = useState('') const [proxyAddressError, setProxyAddressError] = useState('') const multiFields = useRef>([]) const initializeFields = useRef>([]) @@ -37,6 +35,12 @@ export function ContractGUI (props: ContractGUIProps) { } }, [props.deployOption]) + useEffect(() => { + if (!proxyAddress && props.proxy && props.proxy.deployments.length > 0) { + setProxyAddress(props.proxy.deployments[0].address) + } + }, [proxyAddress, props.proxy]) + useEffect(() => { if (props.title) { setTitle(props.title) @@ -178,6 +182,7 @@ export function ContractGUI (props: ContractGUIProps) { 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']) } else { props.clickCallBack(props.funcABI.inputs, basicInput) @@ -223,25 +228,8 @@ export function ContractGUI (props: ContractGUIProps) { setDeployState({ deploy: false, upgrade: value }) } - const handleUseLastProxySelect = (e) => { - const value = e.target.checked - const address = '' /* props.savedProxyAddress */ - - if (value) { - if (address) { - setProxyAddress(address) - setProxyAddressError('') - } else { - setProxyAddressError('No proxy address available') - setProxyAddress('') - } - } - setUseLastProxy(value) - } - - const handleSetProxyAddress = (e) => { + const handleSelectProxyAddress = (e) => { const value = e.target.value - setProxyAddress(value) } @@ -520,51 +508,17 @@ export function ContractGUI (props: ContractGUIProps) { }`} >
-
- - } - tooltipId="proxyAddressTooltip" - placement="auto" - tooltipClasses="text-wrap" - > - - -
- { - !useLastProxy ?
- - }> - validateProxyAddress(proxyAddress) } /> - + { proxyAddressError && { proxyAddressError } } -
: - - } +
- + ) : null} ); diff --git a/libs/remix-ui/run-tab/src/lib/run-tab.tsx b/libs/remix-ui/run-tab/src/lib/run-tab.tsx index 05b2614151..7ad8649860 100644 --- a/libs/remix-ui/run-tab/src/lib/run-tab.tsx +++ b/libs/remix-ui/run-tab/src/lib/run-tab.tsx @@ -27,7 +27,7 @@ import { storeNewScenario, runScenario, setScenarioPath, getFuncABIValues, setNetworkName, updateSelectedContract, - syncContracts, isValidProxyAddress + syncContracts, isValidProxyAddress, isValidProxyUpgrade } from './actions' import './css/run-tab.css' import { PublishToStorage } from '@remix-ui/publish-to-storage' @@ -242,6 +242,7 @@ export function RunTabUI (props: RunTabProps) { setSelectedContract={updateSelectedContract} remixdActivated={runTab.remixdActivated} isValidProxyAddress={isValidProxyAddress} + isValidProxyUpgrade={isValidProxyUpgrade} proxy={runTab.proxy} /> void remixdActivated: boolean, isValidProxyAddress?: (address: string) => Promise, + isValidProxyUpgrade?: (proxyAddress: string, contractName: string, solcInput: SolcInput, solcOuput: SolcOutput) => void, proxy: { deployments: { address: string, date: Date }[] } } @@ -359,7 +361,8 @@ export interface ContractGUIProps { deployOption?: { title: DeployMode, active: boolean }[], initializerOptions?: DeployOption, proxy?: { deployments: { address: string, date: Date }[] }, - isValidProxyAddress?: (address: string) => Promise + isValidProxyAddress?: (address: string) => Promise, + isValidProxyUpgrade?: (proxyAddress: string) => void } export interface MainnetProps { network: Network,