diff --git a/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts b/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts index 9c2fc9c263..fdbc6e2b00 100644 --- a/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts +++ b/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts @@ -37,7 +37,7 @@ export class OpenZeppelinProxy extends Plugin { const ast = data.sources[file].ast if (this.kind === 'UUPS') { - const options = await (this.getUUPSContractOptions(contracts, ast, file)) + const options = await this.getUUPSContractOptions(contracts, ast, file) return options } @@ -46,28 +46,36 @@ export class OpenZeppelinProxy extends Plugin { async getUUPSContractOptions(contracts, ast, file) { const options = {} - await Promise.all(Object.keys(contracts).map(async (name) => { - if (ast) { - const UUPSSymbol = ast.exportedSymbols[UUPS] ? ast.exportedSymbols[UUPS][0] : null - - await Promise.all(ast.absolutePath === file && ast.nodes.map(async (node) => { - if (node.name === name && node.linearizedBaseContracts.includes(UUPSSymbol)) { - const abi = contracts[name].abi - const initializeInput = abi.find(node => node.name === 'initialize') - const isDeployWithProxyEnabled: boolean = await this.call('config', 'getAppParameter', EnableProxyURLParam) || false - const isDeployWithUpgradeEnabled: boolean = await this.call('config', 'getAppParameter', EnableUpgradeURLParam) || false - - options[name] = { - options: [{ title: 'Deploy with Proxy', active: isDeployWithProxyEnabled }, { title: 'Upgrade with Proxy', active: isDeployWithUpgradeEnabled }], - initializeOptions: { - inputs: initializeInput, - initializeInputs: initializeInput ? this.blockchain.getInputs(initializeInput) : null - } - } - } - })) - } - })) + await Promise.all( + Object.keys(contracts).map(async (name) => { + if (ast) { + const UUPSSymbol = ast.exportedSymbols[UUPS] ? ast.exportedSymbols[UUPS][0] : null + + await Promise.all( + ast.absolutePath === file && + ast.nodes.map(async (node) => { + if (node.name === name && node.linearizedBaseContracts.includes(UUPSSymbol)) { + const abi = contracts[name].abi + const initializeInput = abi.find((node) => node.name === 'initialize') + const isDeployWithProxyEnabled: boolean = (await this.call('config', 'getAppParameter', EnableProxyURLParam)) || false + const isDeployWithUpgradeEnabled: boolean = (await this.call('config', 'getAppParameter', EnableUpgradeURLParam)) || false + + options[name] = { + options: [ + { title: 'Deploy with Proxy', active: isDeployWithProxyEnabled }, + { title: 'Upgrade with Proxy', active: isDeployWithUpgradeEnabled }, + ], + initializeOptions: { + inputs: initializeInput, + initializeInputs: initializeInput ? this.blockchain.getInputs(initializeInput) : null, + }, + } + } + }) + ) + } + }) + ) return options } @@ -88,6 +96,7 @@ export class OpenZeppelinProxy extends Plugin { } async deployUUPSProxy(implAddress: string, _data: string, implementationContractObject): Promise { + const args = [implAddress, _data] const constructorData = await this.blockchain.getEncodedParams(args, UUPSfunAbi) const proxyName = 'ERC1967Proxy' @@ -98,9 +107,18 @@ export class OpenZeppelinProxy extends Plugin { funAbi: UUPSfunAbi, funArgs: args, linkReferences: {}, - dataHex: UUPSBytecodeV5 + constructorData.replace('0x', '') + dataHex: UUPSBytecodeV5 + constructorData.replace('0x', ''), + } + // check if implementation contract has a function called UPGRADE_INTERFACE_VERSION + // if it hasn't then we use the old bytecode pre 5.0.0 + const hasUpgradeVersionCall = implementationContractObject.abi.find((abi) => abi.name === 'UPGRADE_INTERFACE_VERSION') + if (!hasUpgradeVersionCall) { + data.contractByteCode = UUPSBytecode + data.dataHex = UUPSBytecode + constructorData.replace('0x', '') + this.call('terminal', 'logHtml', `Using ERC1967 < 5.0.0 for proxy deployment...`) + }else{ + this.call('terminal', 'logHtml', `Using ERC1967 >= 5.0.0 for proxy deployment...`) } - // re-use implementation contract's ABI for UI display in udapp and change name to proxy name. implementationContractObject.contractName = implementationContractObject.name implementationContractObject.implementationAddress = implAddress @@ -118,57 +136,60 @@ export class OpenZeppelinProxy extends Plugin { dataHex: dataHex, funAbi: GETUUPSProxyVersionAbi, contractName: proxyName, - funArgs: [] + funArgs: [], }, - useCall: true + useCall: true, } // re-use implementation contract's ABI for UI display in udapp and change name to proxy name. newImplementationContractObject.contractName = newImplementationContractObject.name newImplementationContractObject.implementationAddress = newImplAddress newImplementationContractObject.name = proxyName - - await this.blockchain.runTx(args, () => { }, () => { }, () => { }, async (error, txResult, _address, returnValue) => { - let version = '4.8.3' - if (error) { - console.log(`error: ${error.message ? error.message : error}`) - console.log(`Will use version 4.8.3 of the proxy...`) - }else{ - const response = txFormat.decodeResponse(returnValue, GETUUPSProxyVersionAbi) - version = response[0].split('string: ')[1] - // check if version is >= 5.0.0 - console.log('version', response) - } - if (semver.gte(version, '5.0.0')) { - - const fnData = await this.blockchain.getEncodedFunctionHex([newImplAddress, "0x"], UUPSupgradeToAndCallAbi) - - const data = { - contractABI: UUPSABI, - contractName: proxyName, - funAbi: UUPSupgradeToAndCallAbi, - funArgs: [newImplAddress, "0x"], - linkReferences: {}, - dataHex: fnData.replace('0x', '') + await this.blockchain.runTx( + args, + () => {}, + () => {}, + () => {}, + async (error, txResult, _address, returnValue) => { + let version = '4.8.3' + if (error) { + console.log(`error: ${error.message ? error.message : error}`) + console.log(`Will use version 4.8.3 of the proxy...`) + } else { + const response = txFormat.decodeResponse(returnValue, GETUUPSProxyVersionAbi) + version = response[0].split('string: ')[1] + // check if version is >= 5.0.0 + console.log('version', response) } - this.blockchain.upgradeProxy(proxyAddress, newImplAddress, data, newImplementationContractObject) - } else { - const fnData = await this.blockchain.getEncodedFunctionHex([newImplAddress], UUPSupgradeAbi) - const proxyName = 'ERC1967Proxy' - const data = { - contractABI: UUPSABI, - contractName: proxyName, - funAbi: UUPSupgradeAbi, - funArgs: [newImplAddress], - linkReferences: {}, - dataHex: fnData.replace('0x', '') - } + if (semver.gte(version, '5.0.0')) { + const fnData = await this.blockchain.getEncodedFunctionHex([newImplAddress, '0x'], UUPSupgradeToAndCallAbi) - this.blockchain.upgradeProxy(proxyAddress, newImplAddress, data, newImplementationContractObject) + const data = { + contractABI: UUPSABI, + contractName: proxyName, + funAbi: UUPSupgradeToAndCallAbi, + funArgs: [newImplAddress, '0x'], + linkReferences: {}, + dataHex: fnData.replace('0x', ''), + } + this.call('terminal', 'logHtml', `Using ERC1967 >= 5.0.0 for proxy upgrade...`) + this.blockchain.upgradeProxy(proxyAddress, newImplAddress, data, newImplementationContractObject) + } else { + const fnData = await this.blockchain.getEncodedFunctionHex([newImplAddress], UUPSupgradeAbi) + const proxyName = 'ERC1967Proxy' + const data = { + contractABI: UUPSABI, + contractName: proxyName, + funAbi: UUPSupgradeAbi, + funArgs: [newImplAddress], + linkReferences: {}, + dataHex: fnData.replace('0x', ''), + } + this.call('terminal', 'logHtml', `Using ERC1967 < 5.0.0 for proxy upgrade...`) + this.blockchain.upgradeProxy(proxyAddress, newImplAddress, data, newImplementationContractObject) + } } - }) - - + ) } } 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 3929f787b1..dd0b709b39 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/deploy.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/deploy.ts @@ -172,6 +172,7 @@ export const createInstance = async ( _paq.push(['trackEvent', 'udapp', 'DeployOnly', plugin.REACT_API.networkName]) } if (isProxyDeployment) { + console.log('isProxyDeployment', contractObject.abi) const initABI = contractObject.abi.find(abi => abi.name === 'initialize') plugin.call('openzeppelin-proxy', 'executeUUPSProxy', addressToString(address), args, initABI, contractObject)