diff --git a/apps/remix-ide-e2e/src/tests/proxy_oz_v4.test.ts b/apps/remix-ide-e2e/src/tests/proxy_oz_v4.test.ts new file mode 100644 index 00000000000..f4d21d6cbd5 --- /dev/null +++ b/apps/remix-ide-e2e/src/tests/proxy_oz_v4.test.ts @@ -0,0 +1,345 @@ +'use strict' +import { NightwatchBrowser } from 'nightwatch' +import init from '../helpers/init' + +let firstProxyAddress: string +let lastProxyAddress: string +let shortenedFirstAddress: string +let shortenedLastAddress: string +module.exports = { + '@disabled': true, + before: function (browser: NightwatchBrowser, done: VoidFunction) { + init(browser, done) + }, + + '@sources': function () { + return sources + }, + + 'Should set the compiler version to 8.19': function(browser: NightwatchBrowser) { + browser.setSolidityCompilerVersion('soljson-v0.8.19+commit.7dd6d404.js') + }, + + 'Should show deploy proxy option for UUPS upgradeable contract #group1': function (browser: NightwatchBrowser) { + browser + .addFile('myTokenV1.sol', sources[0]['myTokenV1.sol']) + .clickLaunchIcon('solidity') + .pause(2000) + // because the compilatiom imports are slow and sometimes stop loading (not sure why, it's bug) we need to recompile and check to see if the files are really in de FS + .click('[data-id="compilerContainerCompileBtn"]') + .clickLaunchIcon('filePanel') + .isVisible({ + selector: '*[data-id="treeViewDivtreeViewItem.deps/npm/@openzeppelin/contracts-upgradeable@4.8.3/proxy/beacon/IBeaconUpgradeable.sol"]', + timeout: 120000, + suppressNotFoundErrors: true + }) + .clickLaunchIcon('solidity') + .click('[data-id="compilerContainerCompileBtn"]') + .clickLaunchIcon('filePanel') + .isVisible({ + selector: '*[data-id="treeViewDivtreeViewItem.deps/npm/@openzeppelin/contracts-upgradeable@4.8.3/proxy/beacon/IBeaconUpgradeable.sol"]', + timeout: 120000, + suppressNotFoundErrors: true + }) + .clickLaunchIcon('solidity') + .click('[data-id="compilerContainerCompileBtn"]') + .clickLaunchIcon('filePanel') + .waitForElementVisible({ + selector: '*[data-id="treeViewDivtreeViewItem.deps/npm/@openzeppelin/contracts-upgradeable@4.8.3/proxy/beacon/IBeaconUpgradeable.sol"]', + timeout: 120000, + }) + .clickLaunchIcon('solidity') + .waitForElementPresent('select[id="compiledContracts"] option[value=MyToken]', 60000) + .clickLaunchIcon('udapp') + .click('select.udapp_contractNames') + .click('select.udapp_contractNames option[value=MyToken]') + .waitForElementPresent('[data-id="contractGUIDeployWithProxyLabel"]') + .waitForElementPresent('[data-id="contractGUIUpgradeImplementationLabel"]') + }, + + 'Should show upgrade proxy option for child contract inheriting UUPS parent contract #group1': function (browser: NightwatchBrowser) { + browser + .addFile('myTokenV2.sol', sources[1]['myTokenV2.sol']) + .clickLaunchIcon('solidity') + .assert.visible('[data-id="compilerContainerCompileBtn"]') + .click('[data-id="compilerContainerCompileBtn"]') + .waitForElementPresent('select[id="compiledContracts"] option[value=MyTokenV2]', 60000) + .clickLaunchIcon('udapp') + .click('select.udapp_contractNames') + .click('select.udapp_contractNames option[value=MyTokenV2]') + .waitForElementPresent('[data-id="contractGUIDeployWithProxyLabel"]') + .waitForElementPresent('[data-id="contractGUIUpgradeImplementationLabel"]') + }, + + 'Should deploy proxy without initialize parameters #group1': function (browser: NightwatchBrowser) { + browser + .openFile('myTokenV1.sol') + .clickLaunchIcon('solidity') + .assert.visible('[data-id="compilerContainerCompileBtn"]') + .click('[data-id="compilerContainerCompileBtn"]') + .waitForElementPresent('select[id="compiledContracts"] option[value=MyToken]', 60000) + .clickLaunchIcon('udapp') + .click('select.udapp_contractNames') + .click('select.udapp_contractNames option[value=MyToken]') + .verify.visible('[data-id="contractGUIDeployWithProxyLabel"]') + .waitForElementPresent('[data-id="contractGUIDeployWithProxyLabel"]') + .click('[data-id="contractGUIDeployWithProxyLabel"]') + .createContract('') + .waitForElementContainsText('[data-id="udappNotifyModalDialogModalTitle-react"]', 'Deploy Implementation & Proxy (ERC1967)') + .waitForElementVisible('[data-id="udappNotify-modal-footer-ok-react"]') + .click('[data-id="udappNotify-modal-footer-ok-react"]') + .waitForElementContainsText('[data-id="confirmProxyDeploymentModalDialogModalTitle-react"]', 'Confirm Deploy Proxy (ERC1967)') + .waitForElementVisible('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') + .click('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') + .waitForElementPresent('[data-id="universalDappUiTitleExpander0"]') + .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') + .waitForElementContainsText('*[data-id="terminalJournal"]', 'Deploying ERC1967 < 5.0.0 as proxy...', 60000) + }, + + 'Should interact with deployed contract via ERC1967 (proxy) #group1': function (browser: NightwatchBrowser) { + browser + .getAddressAtPosition(1, (address) => { + firstProxyAddress = address + shortenedFirstAddress = address.slice(0, 5) + '...' + address.slice(address.length - 5, address.length) + }) + .clickInstance(1) + .perform((done) => { + browser.testConstantFunction(firstProxyAddress, 'name - call', null, '0:\nstring: MyToken').perform(() => { + done() + }) + }) + .perform((done) => { + browser.testConstantFunction(firstProxyAddress, 'symbol - call', null, '0:\nstring: MTK').perform(() => { + done() + }) + }) + }, + + 'Should deploy proxy with initialize parameters #group1': function (browser: NightwatchBrowser) { + browser + .waitForElementPresent('[data-id="deployAndRunClearInstances"]') + .click('[data-id="deployAndRunClearInstances"]') + .addFile('initializeProxy.sol', sources[2]['initializeProxy.sol']) + .clickLaunchIcon('solidity') + .assert.visible('[data-id="compilerContainerCompileBtn"]') + .click('[data-id="compilerContainerCompileBtn"]') + .waitForElementPresent('select[id="compiledContracts"] option[value=MyInitializedToken]', 60000) + .clickLaunchIcon('udapp') + .click('select.udapp_contractNames') + .click('select.udapp_contractNames option[value=MyInitializedToken]') + .waitForElementPresent('[data-id="contractGUIDeployWithProxyLabel"]') + .click('[data-id="contractGUIDeployWithProxyLabel"]') + .useXpath() + .waitForElementPresent('//*[@id="runTabView"]/div/div[2]/div[3]/div[1]/div/div[1]/div[4]/div/div[1]/input') + .waitForElementPresent('//*[@id="runTabView"]/div/div[2]/div[3]/div[1]/div/div[1]/div[4]/div/div[2]/input') + .setValue('//*[@id="runTabView"]/div/div[2]/div[3]/div[1]/div/div[1]/div[4]/div/div[1]/input', 'Remix') + .setValue('//*[@id="runTabView"]/div/div[2]/div[3]/div[1]/div/div[1]/div[4]/div/div[2]/input', "R") + .useCss() + .createContract('') + .waitForElementContainsText('[data-id="udappNotifyModalDialogModalTitle-react"]', 'Deploy Implementation & Proxy (ERC1967)') + .waitForElementVisible('[data-id="udappNotify-modal-footer-ok-react"]') + .click('[data-id="udappNotify-modal-footer-ok-react"]') + .waitForElementContainsText('[data-id="confirmProxyDeploymentModalDialogModalTitle-react"]', 'Confirm Deploy Proxy (ERC1967)') + .waitForElementVisible('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') + .click('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') + .waitForElementPresent('[data-id="universalDappUiTitleExpander0"]') + .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') + .waitForElementContainsText('*[data-id="terminalJournal"]', 'Deploying ERC1967 < 5.0.0 as proxy...', 60000) + }, + + 'Should interact with initialized contract to verify parameters #group1': function (browser: NightwatchBrowser) { + browser + .getAddressAtPosition(1, (address) => { + lastProxyAddress = address + shortenedLastAddress = address.slice(0, 5) + '...' + address.slice(address.length - 5, address.length) + }) + .clickInstance(1) + .perform((done) => { + browser.testConstantFunction(lastProxyAddress, 'name - call', null, '0:\nstring: Remix').perform(() => { + done() + }) + }) + .perform((done) => { + browser.testConstantFunction(lastProxyAddress, 'symbol - call', null, '0:\nstring: R').perform(() => { + done() + }) + }) + }, + + 'Should upgrade contract by selecting a previously deployed proxy address from dropdown (MyTokenV1 to MyTokenV2) #group1': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="terminalClearConsole"]') + .waitForElementPresent('[data-id="deployAndRunClearInstances"]') + .click('[data-id="deployAndRunClearInstances"]') + .openFile('myTokenV2.sol') + .clickLaunchIcon('solidity') + .assert.visible('[data-id="compilerContainerCompileBtn"]') + .click('[data-id="compilerContainerCompileBtn"]') + .waitForElementPresent('select[id="compiledContracts"] option[value=MyTokenV2]', 60000) + .clickLaunchIcon('udapp') + .click('select.udapp_contractNames') + .click('select.udapp_contractNames option[value=MyTokenV2]') + .waitForElementPresent('[data-id="contractGUIUpgradeImplementationLabel"]') + .click('[data-id="contractGUIUpgradeImplementationLabel"]') + .waitForElementPresent('[data-id="toggleProxyAddressDropdown"]') + .click('[data-id="toggleProxyAddressDropdown"]') + .waitForElementVisible('[data-id="proxy-dropdown-items"]') + .assert.textContains('[data-id="proxy-dropdown-items"]', shortenedFirstAddress) + .assert.textContains('[data-id="proxy-dropdown-items"]', shortenedLastAddress) + .click('[data-id="proxyAddress1"]') + .createContract('') + .waitForElementContainsText('[data-id="udappNotifyModalDialogModalTitle-react"]', 'Deploy Implementation & Update Proxy') + .waitForElementVisible('[data-id="udappNotify-modal-footer-ok-react"]') + .click('[data-id="udappNotify-modal-footer-ok-react"]') + .waitForElementContainsText('[data-id="confirmProxyDeploymentModalDialogModalTitle-react"]', 'Confirm Update Proxy (ERC1967)') + .waitForElementVisible('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') + .click( + { + selector: '[data-id="confirmProxyDeployment-modal-footer-ok-react"]', + }) + .waitForElementPresent('[data-id="universalDappUiTitleExpander0"]') + .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') + .waitForElementContainsText('*[data-id="terminalJournal"]', 'Using ERC1967 < 5.0.0 for the proxy upgrade..', 60000) + }, + + 'Should interact with upgraded function in contract MyTokenV2 #group1': function (browser: NightwatchBrowser) { + browser + .clickInstance(1) + .perform((done) => { + browser.testConstantFunction(lastProxyAddress, 'version - call', null, '0:\nstring: MyTokenV2!').perform(() => { + done() + }) + }) + }, + + 'Should upgrade contract by providing proxy address in input field (MyTokenV1 to MyTokenV2) #group1': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="terminalClearConsole"]') + .waitForElementPresent('[data-id="deployAndRunClearInstances"]') + .click('[data-id="deployAndRunClearInstances"]') + .openFile('myTokenV2.sol') + .clickLaunchIcon('solidity') + .assert.visible('[data-id="compilerContainerCompileBtn"]') + .click('[data-id="compilerContainerCompileBtn"]') + .waitForElementPresent('select[id="compiledContracts"] option[value=MyTokenV2]', 60000) + .clickLaunchIcon('udapp') + .click('select.udapp_contractNames') + .click('select.udapp_contractNames option[value=MyTokenV2]') + .waitForElementPresent('[data-id="contractGUIUpgradeImplementationLabel"]') + .waitForElementPresent('[data-id="toggleProxyAddressDropdown"]') + .clearValue('[data-id="ERC1967AddressInput"]') + .setValue('[data-id="ERC1967AddressInput"]', firstProxyAddress) + .createContract('') + .waitForElementContainsText('[data-id="udappNotifyModalDialogModalTitle-react"]', 'Deploy Implementation & Update Proxy') + .waitForElementVisible('[data-id="udappNotify-modal-footer-ok-react"]') + .click('[data-id="udappNotify-modal-footer-ok-react"]') + .waitForElementContainsText('[data-id="confirmProxyDeploymentModalDialogModalTitle-react"]', 'Confirm Update Proxy (ERC1967)') + .waitForElementVisible('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') + .click('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') + .waitForElementPresent('[data-id="universalDappUiTitleExpander0"]') + .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') + .waitForElementContainsText('*[data-id="terminalJournal"]', 'Using ERC1967 < 5.0.0 for the proxy upgrade..', 60000) + }, + + 'Should interact with upgraded contract through provided proxy address #group1': function (browser: NightwatchBrowser) { + browser + .clearConsole() + .clickInstance(1) + .perform((done) => { + browser.testConstantFunction(firstProxyAddress, 'version - call', null, '0:\nstring: MyTokenV2!').perform(() => { + done() + }) + }) + }, + 'Should debug the call': function(browser: NightwatchBrowser) { + browser + .debugTransaction(0) + .waitForElementVisible({ + locateStrategy: 'xpath', + selector: '//*[@data-id="treeViewLivm trace step" and contains(.,"11")]', + timeout: 60000 + }) + .goToVMTraceStep(146) + .waitForElementContainsText('*[data-id="functionPanel"]', 'version()', 60000) + .end() + } +} + + +const sources = [ + { + 'myTokenV1.sol': { + content: ` + // SPDX-License-Identifier: MIT + pragma solidity ^0.8.4; + + import "@openzeppelin/contracts-upgradeable@4.8.3/token/ERC721/ERC721Upgradeable.sol"; + import "@openzeppelin/contracts-upgradeable@4.8.3/access/OwnableUpgradeable.sol"; + import "@openzeppelin/contracts-upgradeable@4.8.3/proxy/utils/Initializable.sol"; + import "@openzeppelin/contracts-upgradeable@4.8.3/proxy/utils/UUPSUpgradeable.sol"; + + contract MyToken is Initializable, ERC721Upgradeable, OwnableUpgradeable, UUPSUpgradeable { + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize() initializer public { + __ERC721_init("MyToken", "MTK"); + __Ownable_init(); + __UUPSUpgradeable_init(); + } + + function _authorizeUpgrade(address newImplementation) + internal + onlyOwner + override + {} + } + ` + } + }, { + 'myTokenV2.sol': { + content: ` + import "./myTokenV1.sol"; + + contract MyTokenV2 is MyToken { + function version () public view returns (string memory) { + return "MyTokenV2!"; + } + } + ` + } + }, { + 'initializeProxy.sol': { + content: ` + // SPDX-License-Identifier: MIT + pragma solidity ^0.8.4; + + import "@openzeppelin/contracts-upgradeable@4.8.3/token/ERC721/ERC721Upgradeable.sol"; + import "@openzeppelin/contracts-upgradeable@4.8.3/access/OwnableUpgradeable.sol"; + import "@openzeppelin/contracts-upgradeable@4.8.3/proxy/utils/Initializable.sol"; + import "@openzeppelin/contracts-upgradeable@4.8.3/proxy/utils/UUPSUpgradeable.sol"; + + contract MyInitializedToken is Initializable, ERC721Upgradeable, OwnableUpgradeable, UUPSUpgradeable { + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize(string memory tokenName, string memory tokenSymbol) initializer public { + __ERC721_init(tokenName, tokenSymbol); + __Ownable_init(); + __UUPSUpgradeable_init(); + } + + function _authorizeUpgrade(address newImplementation) + internal + onlyOwner + override + {} + } + ` + } + } +] \ No newline at end of file diff --git a/apps/remix-ide-e2e/src/tests/proxy.test.ts b/apps/remix-ide-e2e/src/tests/proxy_oz_v5.test.ts similarity index 94% rename from apps/remix-ide-e2e/src/tests/proxy.test.ts rename to apps/remix-ide-e2e/src/tests/proxy_oz_v5.test.ts index 331dafd3eab..dbe0052e731 100644 --- a/apps/remix-ide-e2e/src/tests/proxy.test.ts +++ b/apps/remix-ide-e2e/src/tests/proxy_oz_v5.test.ts @@ -91,6 +91,7 @@ module.exports = { .click('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander0"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') + .waitForElementContainsText('*[data-id="terminalJournal"]', 'Deploying ERC1967 >= 5.0.0 as proxy...') }, 'Should interact with deployed contract via ERC1967 (proxy) #group1': function (browser: NightwatchBrowser) { @@ -142,6 +143,7 @@ module.exports = { .click('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander0"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') + .waitForElementContainsText('*[data-id="terminalJournal"]', 'Deploying ERC1967 >= 5.0.0 as proxy...') }, 'Should interact with initialized contract to verify parameters #group1': function (browser: NightwatchBrowser) { @@ -165,6 +167,7 @@ module.exports = { 'Should upgrade contract by selecting a previously deployed proxy address from dropdown (MyTokenV1 to MyTokenV2) #group1': function (browser: NightwatchBrowser) { browser + .click('*[data-id="terminalClearConsole"]') .waitForElementPresent('[data-id="deployAndRunClearInstances"]') .click('[data-id="deployAndRunClearInstances"]') .openFile('myTokenV2.sol') @@ -196,6 +199,7 @@ module.exports = { }) .waitForElementPresent('[data-id="universalDappUiTitleExpander0"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') + .waitForElementContainsText('*[data-id="terminalJournal"]', 'Using ERC1967 >= 5.0.0 for the proxy upgrade...') }, 'Should interact with upgraded function in contract MyTokenV2 #group1': function (browser: NightwatchBrowser) { @@ -210,6 +214,7 @@ module.exports = { 'Should upgrade contract by providing proxy address in input field (MyTokenV1 to MyTokenV2) #group1': function (browser: NightwatchBrowser) { browser + .click('*[data-id="terminalClearConsole"]') .waitForElementPresent('[data-id="deployAndRunClearInstances"]') .click('[data-id="deployAndRunClearInstances"]') .openFile('myTokenV2.sol') @@ -233,17 +238,30 @@ module.exports = { .click('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander0"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') + .waitForElementContainsText('*[data-id="terminalJournal"]', 'Using ERC1967 >= 5.0.0 for the proxy upgrade...') }, 'Should interact with upgraded contract through provided proxy address #group1': function (browser: NightwatchBrowser) { browser + .clearConsole() .clickInstance(1) .perform((done) => { browser.testConstantFunction(firstProxyAddress, 'version - call', null, '0:\nstring: MyTokenV2!').perform(() => { done() }) }) - .end() + }, + 'Should debug the call': function(browser: NightwatchBrowser) { + browser + .debugTransaction(0) + .waitForElementVisible({ + locateStrategy: 'xpath', + selector: '//*[@data-id="treeViewLivm trace step" and contains(.,"7")]', + timeout: 60000 + }) + .goToVMTraceStep(129) + .waitForElementContainsText('*[data-id="functionPanel"]', 'version()', 60000) + .end() } } diff --git a/apps/remix-ide/src/app/tabs/debugger-tab.js b/apps/remix-ide/src/app/tabs/debugger-tab.js index cd06ea4ffa0..03bd6721105 100644 --- a/apps/remix-ide/src/app/tabs/debugger-tab.js +++ b/apps/remix-ide/src/app/tabs/debugger-tab.js @@ -5,7 +5,7 @@ import { ViewPlugin } from '@remixproject/engine-web' import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line import { bleach } from '@remix-ui/helper' -import { compilationFinishedToastMsg, compilingToastMsg, localCompilationToastMsg, notFoundToastMsg, sourceVerificationNotAvailableToastMsg } from '@remix-ui/helper' +import { compilationFinishedToastMsg, compilingToastMsg, notFoundToastMsg, sourceVerificationNotAvailableToastMsg } from '@remix-ui/helper' const css = require('./styles/debugger-tab-styles') const profile = { diff --git a/apps/remix-ide/src/app/tabs/locales/en/debugger.json b/apps/remix-ide/src/app/tabs/locales/en/debugger.json index 035d1604613..dc46390eed4 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/debugger.json +++ b/apps/remix-ide/src/app/tabs/locales/en/debugger.json @@ -2,6 +2,7 @@ "debugger.displayName": "Debugger", "debugger.debuggerConfiguration": "Debugger Configuration", "debugger.stopDebugging": "Stop debugging", + "debugger.provideTxNumber": "Please provide a valid transaction hash", "debugger.startDebugging": "Start debugging", "debugger.placeholder": "Transaction hash, should start with 0x", "debugger.debugLocaNodeLabel": "Force using local node", diff --git a/apps/remix-ide/src/app/tabs/network-module.js b/apps/remix-ide/src/app/tabs/network-module.js index c1cc1e12b59..ea7a1c0c6ef 100644 --- a/apps/remix-ide/src/app/tabs/network-module.js +++ b/apps/remix-ide/src/app/tabs/network-module.js @@ -53,7 +53,7 @@ export class NetworkModule extends Plugin { this.blockchain.addProvider({ name: network.name, provider }) } - /** Remove a network to the list of availble networks */ + /** Remove a network to the list of available networks */ removeNetwork (name) { this.blockchain.removeProvider(name) } diff --git a/apps/remix-ide/src/assets/css/themes/bootstrap-cerulean.min.css b/apps/remix-ide/src/assets/css/themes/bootstrap-cerulean.min.css index f46677c2aa7..3ed6161e195 100644 --- a/apps/remix-ide/src/assets/css/themes/bootstrap-cerulean.min.css +++ b/apps/remix-ide/src/assets/css/themes/bootstrap-cerulean.min.css @@ -2118,6 +2118,7 @@ textarea.form-control { } .btn { + cursor: pointer; display:inline-block; font-weight:400; color:#495057; @@ -2150,7 +2151,8 @@ textarea.form-control { box-shadow:0 0 0 .2rem rgba(47,164,231,.25) } .btn.disabled,.btn:disabled { - opacity:.65 + opacity:.65; + cursor: not-allowed } .btn:not(:disabled):not(.disabled) { cursor:pointer @@ -3928,7 +3930,8 @@ input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn- padding:1.25rem } .card-title { - margin-bottom:.75rem + margin-bottom:.75rem; + color: var(--text); } .card-subtitle { margin-top:-.375rem; diff --git a/apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css b/apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css index 8a43b269126..136e53ff424 100644 --- a/apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css +++ b/apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css @@ -2119,6 +2119,7 @@ textarea.form-control { } .btn { + cursor: pointer;; display:inline-block; font-weight:400; color:#adafae; @@ -2151,7 +2152,8 @@ textarea.form-control { box-shadow:0 0 0 .2rem rgba(42,159,214,.25) } .btn.disabled,.btn:disabled { - opacity:.65 + opacity:.65; + cursor: not-allowed; } .btn:not(:disabled):not(.disabled) { cursor:pointer @@ -3929,7 +3931,8 @@ input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn- padding:1.25rem } .card-title { - margin-bottom:.75rem + margin-bottom:.75rem; + color: var(--text); } .card-subtitle { margin-top:-.375rem; diff --git a/apps/remix-ide/src/assets/css/themes/bootstrap-flatly.min.css b/apps/remix-ide/src/assets/css/themes/bootstrap-flatly.min.css index 30a639ca4db..e9b14b99af5 100644 --- a/apps/remix-ide/src/assets/css/themes/bootstrap-flatly.min.css +++ b/apps/remix-ide/src/assets/css/themes/bootstrap-flatly.min.css @@ -2121,6 +2121,7 @@ textarea.form-control { } .btn { + cursor: pointer; display:inline-block; font-weight:400; color:#212529; @@ -2152,7 +2153,8 @@ textarea.form-control { box-shadow:0 0 0 .2rem rgba(44,62,80,.25) } .btn.disabled,.btn:disabled { - opacity:.65 + opacity:.65; + cursor: not-allowed; } .btn:not(:disabled):not(.disabled) { cursor:pointer @@ -3395,7 +3397,8 @@ input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn- -ms-flex:1 1 auto; flex:1 1 auto; min-height:1px; padding:1.25rem } .card-title { - margin-bottom:.75rem + margin-bottom:.75rem; + color: var(--text); } .card-subtitle { margin-top:-.375rem; margin-bottom:0 diff --git a/apps/remix-ide/src/assets/css/themes/bootstrap-spacelab.min.css b/apps/remix-ide/src/assets/css/themes/bootstrap-spacelab.min.css index 99373822ebb..3129408286d 100644 --- a/apps/remix-ide/src/assets/css/themes/bootstrap-spacelab.min.css +++ b/apps/remix-ide/src/assets/css/themes/bootstrap-spacelab.min.css @@ -2121,6 +2121,7 @@ textarea.form-control { } .btn { + cursor: pointer; display:inline-block; font-weight:400; color:#777; @@ -2153,7 +2154,8 @@ textarea.form-control { box-shadow:0 0 0 .2rem rgba(68,110,155,.25) } .btn.disabled,.btn:disabled { - opacity:.65 + opacity:.65; + cursor: not-allowed } .btn:not(:disabled):not(.disabled) { cursor:pointer @@ -3931,7 +3933,8 @@ input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn- padding:1.25rem } .card-title { - margin-bottom:.75rem + margin-bottom:.75rem; + color: var(--text); } .card-subtitle { margin-top:-.375rem; diff --git a/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css b/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css index d917e3095cc..5c16277d2ea 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css +++ b/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css @@ -2096,6 +2096,7 @@ textarea.form-control.is-invalid { } } .btn { + cursor: pointer; display: inline-block; font-weight: 400; color: #d5d5d5; @@ -2127,6 +2128,7 @@ textarea.form-control.is-invalid { .btn.disabled, .btn:disabled { opacity: 0.65; + cursor: not-allowed } a.btn.disabled, fieldset:disabled a.btn { diff --git a/apps/remix-ide/src/assets/css/themes/remix-candy_ikhg4m.css b/apps/remix-ide/src/assets/css/themes/remix-candy_ikhg4m.css index 99e367a6256..73574f8f5fc 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-candy_ikhg4m.css +++ b/apps/remix-ide/src/assets/css/themes/remix-candy_ikhg4m.css @@ -2314,6 +2314,7 @@ textarea.form-control.is-invalid { } .btn { + cursor: pointer; display: inline-block; font-weight: 400; color: #0f7292; @@ -2346,6 +2347,7 @@ textarea.form-control.is-invalid { .btn.disabled, .btn:disabled { opacity: 0.7; + cursor: not-allowed } a.btn.disabled, @@ -4371,6 +4373,7 @@ input[type="button"].btn-block { .card-title { margin-bottom: 0.75rem; + color: var(--text); } .card-subtitle { diff --git a/apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css b/apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css index 3f21f142477..f512a127c88 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css +++ b/apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css @@ -2097,6 +2097,7 @@ textarea.form-control.is-invalid { } } .btn { + cursor: pointer; display: inline-block; font-weight: 400; color: #fff; @@ -2128,6 +2129,7 @@ textarea.form-control.is-invalid { .btn.disabled, .btn:disabled { opacity: 0.65; + cursor: not-allowed } a.btn.disabled, fieldset:disabled a.btn { diff --git a/apps/remix-ide/src/assets/css/themes/remix-hacker_owl.css b/apps/remix-ide/src/assets/css/themes/remix-hacker_owl.css index 3513bd73fca..0ef4225d575 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-hacker_owl.css +++ b/apps/remix-ide/src/assets/css/themes/remix-hacker_owl.css @@ -2111,6 +2111,7 @@ textarea.form-control.is-invalid { } } .btn { + cursor: pointer; display: inline-block; font-weight: 400; color: #fff; @@ -2142,6 +2143,7 @@ textarea.form-control.is-invalid { .btn.disabled, .btn:disabled { opacity: 0.65; + cursor: not-allowed; } a.btn.disabled, fieldset:disabled a.btn { diff --git a/apps/remix-ide/src/assets/css/themes/remix-light_powaqg.css b/apps/remix-ide/src/assets/css/themes/remix-light_powaqg.css index 8ba6a88f05a..3217df2899a 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-light_powaqg.css +++ b/apps/remix-ide/src/assets/css/themes/remix-light_powaqg.css @@ -2310,6 +2310,7 @@ textarea.form-control.is-invalid { } .btn { + cursor: pointer; display: inline-block; font-weight: 400; color: #2e3145; @@ -2342,6 +2343,7 @@ textarea.form-control.is-invalid { .btn.disabled, .btn:disabled { opacity: 0.7; + cursor: not-allowed; } a.btn.disabled, @@ -4367,6 +4369,7 @@ input[type="button"].btn-block { .card-title { margin-bottom: 0.75rem; + color: var(--text); } .card-subtitle { diff --git a/apps/remix-ide/src/assets/css/themes/remix-midcentury_hrzph3.css b/apps/remix-ide/src/assets/css/themes/remix-midcentury_hrzph3.css index 5df1a16a34b..f64bc8d01bc 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-midcentury_hrzph3.css +++ b/apps/remix-ide/src/assets/css/themes/remix-midcentury_hrzph3.css @@ -2315,6 +2315,7 @@ textarea.form-control.is-invalid { } .btn { + cursor: pointer; display: inline-block; font-weight: 400; color: #062809; @@ -2347,6 +2348,7 @@ textarea.form-control.is-invalid { .btn.disabled, .btn:disabled { opacity: 0.7; + cursor: not-allowed; } a.btn.disabled, @@ -4373,6 +4375,7 @@ input[type="button"].btn-block { .card-title { margin-bottom: 0.75rem; + color: var(--text); } .card-subtitle { diff --git a/apps/remix-ide/src/assets/css/themes/remix-unicorn.css b/apps/remix-ide/src/assets/css/themes/remix-unicorn.css index cf627d02c01..ebf508ff83e 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-unicorn.css +++ b/apps/remix-ide/src/assets/css/themes/remix-unicorn.css @@ -2313,6 +2313,7 @@ textarea.form-control.is-invalid { } .btn { + cursor: pointer; display: inline-block; font-weight: 400; color: #2e3145; @@ -2346,6 +2347,7 @@ textarea.form-control.is-invalid { .btn.disabled, .btn:disabled { opacity: 0.7; + cursor: not-allowed; } a.btn.disabled, @@ -4371,6 +4373,7 @@ input[type="button"].btn-block { .card-title { margin-bottom: 0.75rem; + color: var(--text); } .card-subtitle { diff --git a/apps/remix-ide/src/assets/css/themes/remix-violet.css b/apps/remix-ide/src/assets/css/themes/remix-violet.css index 0b3f629e819..275d0f0907e 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-violet.css +++ b/apps/remix-ide/src/assets/css/themes/remix-violet.css @@ -2310,6 +2310,7 @@ textarea.form-control.is-invalid { } .btn { + cursor: pointer; display: inline-block; font-weight: 400; color: #2e3145; @@ -2342,6 +2343,7 @@ textarea.form-control.is-invalid { .btn.disabled, .btn:disabled { opacity: 0.7; + cursor: not-allowed; } a.btn.disabled, @@ -4367,6 +4369,7 @@ input[type="button"].btn-block { .card-title { margin-bottom: 0.75rem; + color: var(--text); } .card-subtitle { diff --git a/libs/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts b/libs/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts index 6d258d5909b..9818c4a925d 100644 --- a/libs/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts +++ b/libs/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts @@ -427,7 +427,7 @@ function getLibraryCallMemberName (funcCall: FunctionCallAstNode): string { * function baz() { * bar(10) => foo.bar(uint) * @func {ASTNode} function call node - * @func {ASTNode} contract defintion + * @func {ASTNode} contract definition * @return {string} full qualified identifier for the function call */ function getFullQualifiedFunctionCallIdent (contract: ContractDefinitionAstNode, func: FunctionCallAstNode): string { @@ -468,8 +468,8 @@ function isStatement (node: any): boolean { // #################### Complex Node Identification /** - * True if function defintion has function body - * @funcNode {ASTNode} function defintion node + * True if function definition has function body + * @funcNode {ASTNode} function definition node * @return {bool} */ function hasFunctionBody (funcNode: FunctionDefinitionAstNode): boolean { @@ -630,7 +630,7 @@ function isStateVariable (name: string, stateVariables: VariableDeclarationAstNo } /** - * True if is function defintion that is flaged as constant + * True if is function definition that is flaged as constant * @node {ASTNode} some AstNode * @return {bool} */ @@ -648,7 +648,7 @@ function isVariableTurnedIntoGetter (varDeclNode: VariableDeclarationAstNode): b } /** - * True if is function defintion has payable modifier + * True if is function definition has payable modifier * @node {ASTNode} some AstNode * @return {bool} */ @@ -743,7 +743,7 @@ function isFullyImplementedContract (node: ContractDefinitionAstNode): boolean { } /** - * True if it is a library contract defintion + * True if it is a library contract definition * @node {ASTNode} some AstNode * @return {bool} */ diff --git a/libs/remix-astwalker/src/sourceMappings.ts b/libs/remix-astwalker/src/sourceMappings.ts index 869f4959462..69b279d608f 100644 --- a/libs/remix-astwalker/src/sourceMappings.ts +++ b/libs/remix-astwalker/src/sourceMappings.ts @@ -56,7 +56,7 @@ export function sourceLocationFromSrc (src: string): Location { /** * Routines for retrieving solc AST object(s) using some criteria, usually - * includng "src' information. + * including "src' information. */ // eslint-disable-next-line no-redeclare export class SourceMappings { diff --git a/libs/remix-astwalker/src/types.ts b/libs/remix-astwalker/src/types.ts index 784323d2210..469d32c9144 100644 --- a/libs/remix-astwalker/src/types.ts +++ b/libs/remix-astwalker/src/types.ts @@ -6,7 +6,7 @@ export interface Location { file: number; // Would it be clearer to call this a file index? } -// This is intended to be compatibile with VScode's Position. +// This is intended to be compatible with VScode's Position. // However it is pretty common with other things too. // Note: File index is missing here export interface LineColPosition { @@ -14,7 +14,7 @@ export interface LineColPosition { readonly character: number; } -// This is intended to be compatibile with vscode's Range +// This is intended to be compatible with vscode's Range // However it is pretty common with other things too. // Note: File index is missing here export interface LineColRange { diff --git a/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts b/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts index 3030321f93e..d004888a58d 100644 --- a/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts +++ b/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts @@ -4,7 +4,7 @@ import { util } from '@remix-project/remix-lib' import { toChecksumAddress } from '@ethereumjs/util' import { fetchContractFromEtherscan } from './helpers/fetch-etherscan' import { fetchContractFromSourcify } from './helpers/fetch-sourcify' -import { UUPSDeployedByteCode, UUPSCompilerVersion, UUPSOptimize, UUPSRuns, UUPSEvmVersion, UUPSLanguage } from './constants/uups' +import { UUPSDeployedByteCode, UUPSCompilerVersion, UUPSOptimize, UUPSRuns, UUPSEvmVersion, UUPSLanguage, UUPSDeployedByteCodeV5, UUPSCompilerVersionV5 } from './constants/uups' const profile = { name: 'fetchAndCompile', @@ -84,6 +84,34 @@ export class FetchAndCompile extends Plugin { return compData } + if (codeAtAddress === '0x' + UUPSDeployedByteCodeV5) { // proxy + const settings = { + version: UUPSCompilerVersionV5, + language: UUPSLanguage, + evmVersion: UUPSEvmVersion, + optimize: UUPSOptimize, + runs: UUPSRuns + } + const proxyUrl = 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.0.0/contracts/proxy/ERC1967/ERC1967Proxy.sol' + const compilationTargets = { + 'proxy.sol': { content: `import "${proxyUrl}";` } + } + const compData = await compile( + compilationTargets, + settings, + async (url, cb) => { + // we first try to resolve the content from the compilation target using a more appropiate path + const path = `${targetPath}/${url}` + if (compilationTargets[path] && compilationTargets[path].content) { + return cb(null, compilationTargets[path].content) + } else { + await this.call('contentImport', 'resolveAndSave', url).then((result) => cb(null, result)).catch((error) => cb(error.message)) + } + }) + await this.call('compilerArtefacts', 'addResolvedContract', contractAddress, compData) + return compData + } + // sometimes when doing an internal call, the only available artifact is the Solidity interface. // resolving addresses of internal call would allow to step over the source code, even if the declaration was made using an Interface. diff --git a/libs/remix-core-plugin/src/lib/constants/uups.ts b/libs/remix-core-plugin/src/lib/constants/uups.ts index 4e323365cb1..3a07dfdc8dd 100644 --- a/libs/remix-core-plugin/src/lib/constants/uups.ts +++ b/libs/remix-core-plugin/src/lib/constants/uups.ts @@ -2,9 +2,11 @@ export const UUPS = 'UUPSUpgradeable' // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.0/contracts/proxy/ERC1967/ERC1967Proxy.sol // solidity 0.8.7 export const UUPSBytecode = '608060405260405162000c6638038062000c6683398181016040528101906200002991906200041e565b6200003d828260006200004560201b60201c565b5050620007e2565b62000056836200008860201b60201c565b600082511180620000645750805b156200008357620000818383620000df60201b620000371760201c565b505b505050565b62000099816200011560201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b60606200010d838360405180606001604052806027815260200162000c3f60279139620001eb60201b60201c565b905092915050565b6200012b816200027d60201b620000641760201c565b6200016d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001649062000587565b60405180910390fd5b80620001a77f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b620002a060201b620000871760201c565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516200021791906200054a565b600060405180830381855af49150503d806000811462000254576040519150601f19603f3d011682016040523d82523d6000602084013e62000259565b606091505b50915091506200027286838387620002aa60201b60201c565b925050509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000819050919050565b606083156200031b576000835114156200031257620002cf856200027d60201b60201c565b62000311576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200030890620005a9565b60405180910390fd5b5b8290506200032e565b6200032d83836200033660201b60201c565b5b949350505050565b6000825111156200034a5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000380919062000563565b60405180910390fd5b6000620003a06200039a84620005f4565b620005cb565b905082815260208101848484011115620003bf57620003be62000730565b5b620003cc84828562000690565b509392505050565b600081519050620003e581620007c8565b92915050565b600082601f8301126200040357620004026200072b565b5b81516200041584826020860162000389565b91505092915050565b600080604083850312156200043857620004376200073a565b5b60006200044885828601620003d4565b925050602083015167ffffffffffffffff8111156200046c576200046b62000735565b5b6200047a85828601620003eb565b9150509250929050565b600062000491826200062a565b6200049d818562000640565b9350620004af81856020860162000690565b80840191505092915050565b6000620004c88262000635565b620004d481856200064b565b9350620004e681856020860162000690565b620004f1816200073f565b840191505092915050565b60006200050b602d836200064b565b9150620005188262000750565b604082019050919050565b600062000532601d836200064b565b91506200053f826200079f565b602082019050919050565b600062000558828462000484565b915081905092915050565b600060208201905081810360008301526200057f8184620004bb565b905092915050565b60006020820190508181036000830152620005a281620004fc565b9050919050565b60006020820190508181036000830152620005c48162000523565b9050919050565b6000620005d7620005ea565b9050620005e58282620006c6565b919050565b6000604051905090565b600067ffffffffffffffff821115620006125762000611620006fc565b5b6200061d826200073f565b9050602081019050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b6000620006698262000670565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b83811015620006b057808201518184015260208101905062000693565b83811115620006c0576000848401525b50505050565b620006d1826200073f565b810181811067ffffffffffffffff82111715620006f357620006f2620006fc565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60008201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b620007d3816200065c565b8114620007df57600080fd5b50565b61044d80620007f26000396000f3fe6080604052366100135761001161001d565b005b61001b61001d565b005b610025610091565b610035610030610093565b6100a2565b565b606061005c83836040518060600160405280602781526020016103f1602791396100c8565b905092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000819050919050565b565b600061009d61014e565b905090565b3660008037600080366000845af43d6000803e80600081146100c3573d6000f35b3d6000fd5b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516100f291906102f8565b600060405180830381855af49150503d806000811461012d576040519150601f19603f3d011682016040523d82523d6000602084013e610132565b606091505b5091509150610143868383876101a5565b925050509392505050565b600061017c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b610087565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060831561020857600083511415610200576101c085610064565b6101ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f690610331565b60405180910390fd5b5b829050610213565b610212838361021b565b5b949350505050565b60008251111561022e5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610262919061030f565b60405180910390fd5b600061027682610351565b6102808185610367565b9350610290818560208601610383565b80840191505092915050565b60006102a78261035c565b6102b18185610372565b93506102c1818560208601610383565b6102ca816103b6565b840191505092915050565b60006102e2601d83610372565b91506102ed826103c7565b602082019050919050565b6000610304828461026b565b915081905092915050565b60006020820190508181036000830152610329818461029c565b905092915050565b6000602082019050818103600083015261034a816102d5565b9050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60005b838110156103a1578082015181840152602081019050610386565b838111156103b0576000848401525b50505050565b6000601f19601f8301169050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060008201525056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122055b27d4c39ab82b8890fc1565c3858a1b7f1e0f5780871061f908d7503dcf94e64736f6c63430008070033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564' -export const UUPSBytecodeV5 = '608060405260405161083838038061083883398181016040528101906100259190610501565b61003682825f61003d60201b60201c565b505061071d565b61004c8361007460201b60201c565b5f825111806100585750805b1561006f5761006d83836100c960201b60201c565b505b505050565b610083816100fc60201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b60606100f48383604051806060016040528060278152602001610811602791396101be60201b60201c565b905092915050565b61010b8161024660201b60201c565b61014a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610141906105db565b60405180910390fd5b8061017c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b61026860201b60201c565b5f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60605f808573ffffffffffffffffffffffffffffffffffffffff16856040516101e7919061063d565b5f60405180830381855af49150503d805f811461021f576040519150601f19603f3d011682016040523d82523d5f602084013e610224565b606091505b509150915061023b8683838761027160201b60201c565b925050509392505050565b5f808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f819050919050565b606083156102d8575f8351036102d0576102908561024660201b60201c565b6102cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102c69061069d565b60405180910390fd5b5b8290506102e9565b6102e883836102f160201b60201c565b5b949350505050565b5f825111156103035781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161033791906106fd565b60405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61037a82610351565b9050919050565b61038a81610370565b8114610394575f80fd5b50565b5f815190506103a581610381565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6103f9826103b3565b810181811067ffffffffffffffff82111715610418576104176103c3565b5b80604052505050565b5f61042a610340565b905061043682826103f0565b919050565b5f67ffffffffffffffff821115610455576104546103c3565b5b61045e826103b3565b9050602081019050919050565b5f5b8381101561048857808201518184015260208101905061046d565b5f8484015250505050565b5f6104a56104a08461043b565b610421565b9050828152602081018484840111156104c1576104c06103af565b5b6104cc84828561046b565b509392505050565b5f82601f8301126104e8576104e76103ab565b5b81516104f8848260208601610493565b91505092915050565b5f806040838503121561051757610516610349565b5b5f61052485828601610397565b925050602083015167ffffffffffffffff8111156105455761054461034d565b5b610551858286016104d4565b9150509250929050565b5f82825260208201905092915050565b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e5f8201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b5f6105c5602d8361055b565b91506105d08261056b565b604082019050919050565b5f6020820190508181035f8301526105f2816105b9565b9050919050565b5f81519050919050565b5f81905092915050565b5f610617826105f9565b6106218185610603565b935061063181856020860161046b565b80840191505092915050565b5f610648828461060d565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000005f82015250565b5f610687601d8361055b565b915061069282610653565b602082019050919050565b5f6020820190508181035f8301526106b48161067b565b9050919050565b5f81519050919050565b5f6106cf826106bb565b6106d9818561055b565b93506106e981856020860161046b565b6106f2816103b3565b840191505092915050565b5f6020820190508181035f83015261071581846106c5565b905092915050565b60e8806107295f395ff3fe608060405236601057600e6018565b005b60166018565b005b601e602c565b602a6026602e565b603a565b565b565b5f60356058565b905090565b365f80375f80365f845af43d5f803e805f81146054573d5ff35b3d5ffd5b5f60827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b60a9565b5f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f81905091905056fea2646970667358221220ebc766ba8a493e22f0fe3c66ce0adc94200a52324ee0c954fe8462c2263ba10b64736f6c63430008150033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564' +export const UUPSBytecodeV5 = '60806040526040516106ae3803806106ae833981810160405281019061002591906104f2565b610035828261003c60201b60201c565b50506105ce565b61004b826100c060201b60201c565b8173ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a25f815111156100ad576100a7828261018f60201b60201c565b506100bc565b6100bb61021560201b60201c565b5b5050565b5f8173ffffffffffffffffffffffffffffffffffffffff163b0361011b57806040517f4c9c8ce3000000000000000000000000000000000000000000000000000000008152600401610112919061055b565b60405180910390fd5b8061014d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b61025160201b60201c565b5f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60605f808473ffffffffffffffffffffffffffffffffffffffff16846040516101b891906105b8565b5f60405180830381855af49150503d805f81146101f0576040519150601f19603f3d011682016040523d82523d5f602084013e6101f5565b606091505b509150915061020b85838361025a60201b60201c565b9250505092915050565b5f34111561024f576040517fb398979f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f819050919050565b60608261027557610270826102ed60201b60201c565b6102e5565b5f825114801561029b57505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156102dd57836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016102d4919061055b565b60405180910390fd5b8190506102e6565b5b9392505050565b5f815111156102ff5780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61036b82610342565b9050919050565b61037b81610361565b8114610385575f80fd5b50565b5f8151905061039681610372565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6103ea826103a4565b810181811067ffffffffffffffff82111715610409576104086103b4565b5b80604052505050565b5f61041b610331565b905061042782826103e1565b919050565b5f67ffffffffffffffff821115610446576104456103b4565b5b61044f826103a4565b9050602081019050919050565b5f5b8381101561047957808201518184015260208101905061045e565b5f8484015250505050565b5f6104966104918461042c565b610412565b9050828152602081018484840111156104b2576104b16103a0565b5b6104bd84828561045c565b509392505050565b5f82601f8301126104d9576104d861039c565b5b81516104e9848260208601610484565b91505092915050565b5f80604083850312156105085761050761033a565b5b5f61051585828601610388565b925050602083015167ffffffffffffffff8111156105365761053561033e565b5b610542858286016104c5565b9150509250929050565b61055581610361565b82525050565b5f60208201905061056e5f83018461054c565b92915050565b5f81519050919050565b5f81905092915050565b5f61059282610574565b61059c818561057e565b93506105ac81856020860161045c565b80840191505092915050565b5f6105c38284610588565b915081905092915050565b60d4806105da5f395ff3fe6080604052600a600c565b005b60186014601a565b6026565b565b5f60216044565b905090565b365f80375f80365f845af43d5f803e805f81146040573d5ff35b3d5ffd5b5f606e7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b6095565b5f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f81905091905056fea26469706673582212202e577dc05daa509bce6e6a86e29397d40b31118aea9fcd0aa88768ad25c610f964736f6c63430008150033' export const UUPSDeployedByteCode = '6080604052366100135761001161001d565b005b61001b61001d565b005b610025610091565b610035610030610093565b6100a2565b565b606061005c83836040518060600160405280602781526020016103f1602791396100c8565b905092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000819050919050565b565b600061009d61014e565b905090565b3660008037600080366000845af43d6000803e80600081146100c3573d6000f35b3d6000fd5b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516100f291906102f8565b600060405180830381855af49150503d806000811461012d576040519150601f19603f3d011682016040523d82523d6000602084013e610132565b606091505b5091509150610143868383876101a5565b925050509392505050565b600061017c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b610087565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060831561020857600083511415610200576101c085610064565b6101ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f690610331565b60405180910390fd5b5b829050610213565b610212838361021b565b5b949350505050565b60008251111561022e5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610262919061030f565b60405180910390fd5b600061027682610351565b6102808185610367565b9350610290818560208601610383565b80840191505092915050565b60006102a78261035c565b6102b18185610372565b93506102c1818560208601610383565b6102ca816103b6565b840191505092915050565b60006102e2601d83610372565b91506102ed826103c7565b602082019050919050565b6000610304828461026b565b915081905092915050565b60006020820190508181036000830152610329818461029c565b905092915050565b6000602082019050818103600083015261034a816102d5565b9050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60005b838110156103a1578082015181840152602081019050610386565b838111156103b0576000848401525b50505050565b6000601f19601f8301169050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060008201525056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122055b27d4c39ab82b8890fc1565c3858a1b7f1e0f5780871061f908d7503dcf94e64736f6c63430008070033' +export const UUPSDeployedByteCodeV5 = '6080604052600a600c565b005b60186014601a565b6026565b565b5f60216044565b905090565b365f80375f80365f845af43d5f803e805f81146040573d5ff35b3d5ffd5b5f606e7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5f1b6095565b5f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f81905091905056fea26469706673582212202e577dc05daa509bce6e6a86e29397d40b31118aea9fcd0aa88768ad25c610f964736f6c63430008150033' export const UUPSCompilerVersion = 'soljson-v0.8.7+commit.e28d00a7.js' +export const UUPSCompilerVersionV5 = 'soljson-v0.8.21+commit.d9974bed.js' export const UUPSLanguage = 'Solidity' export const UUPSOptimize = false export const UUPSRuns = 0 @@ -99,6 +101,23 @@ export const UUPSfunAbi = { stateMutability: "payable" } +export const UUPSfunAbiV5 = { + inputs: [ + { + internalType: 'address', + name: 'implementation', + type: 'address', + }, + { + internalType: 'bytes', + name: '_data', + type: 'bytes', + }, + ], + stateMutability: 'payable', + type: 'constructor', +} + export const UUPSupgradeAbi = { "inputs": [ { diff --git a/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts b/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts index 55cbc92aace..661ead7a6f1 100644 --- a/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts +++ b/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts @@ -1,6 +1,6 @@ import { Plugin } from '@remixproject/engine' import { ContractAST, ContractSources, DeployOptions } from '../types/contract' -import { EnableProxyURLParam, EnableUpgradeURLParam, GETUUPSProxyVersionAbi, UUPS, UUPSABI, UUPSBytecode, UUPSBytecodeV5, UUPSfunAbi, UUPSupgradeAbi, UUPSupgradeToAndCallAbi } from './constants/uups' +import { EnableProxyURLParam, EnableUpgradeURLParam, GETUUPSProxyVersionAbi, UUPS, UUPSABI, UUPSBytecode, UUPSBytecodeV5, UUPSfunAbi, UUPSfunAbiV5, UUPSupgradeAbi, UUPSupgradeToAndCallAbi } from './constants/uups' import * as remixLib from '@remix-project/remix-lib' import * as semver from 'semver' const txFormat = remixLib.execution.txFormat @@ -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 } @@ -88,6 +88,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' @@ -95,12 +96,22 @@ export class OpenZeppelinProxy extends Plugin { contractABI: UUPSABI, contractByteCode: UUPSBytecodeV5, contractName: proxyName, - funAbi: UUPSfunAbi, + funAbi: UUPSfunAbiV5, 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', '') + data.funAbi = UUPSfunAbi + this.call('terminal', 'logHtml', `Deploying ERC1967 < 5.0.0 as proxy...`) + }else{ + this.call('terminal', 'logHtml', `Deploying ERC1967 >= 5.0.0 as proxy...`) } - // 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,51 +129,58 @@ 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) => { - if (error) { - throw new Error(`error: ${error.message ? error.message : error}`) - } - const response = txFormat.decodeResponse(returnValue, GETUUPSProxyVersionAbi) - const version = response[0].split('string: ')[1] - // check if version is >= 5.0.0 - 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', '') - } - 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', '') + 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}`) + } else { + const response = txFormat.decodeResponse(returnValue, GETUUPSProxyVersionAbi) + version = response[0].split('string: ')[1] + // check if version is >= 5.0.0 } - this.blockchain.upgradeProxy(proxyAddress, newImplAddress, data, newImplementationContractObject) - } - }) - + 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', ''), + } + this.call('terminal', 'logHtml', `Using ERC1967 >= 5.0.0 for the 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 the proxy upgrade...`) + this.blockchain.upgradeProxy(proxyAddress, newImplAddress, data, newImplementationContractObject) + } + } + ) } -} \ No newline at end of file +} diff --git a/libs/remix-lib/src/execution/txListener.ts b/libs/remix-lib/src/execution/txListener.ts index 960ca63a55b..d4251f02974 100644 --- a/libs/remix-lib/src/execution/txListener.ts +++ b/libs/remix-lib/src/execution/txListener.ts @@ -36,7 +36,7 @@ export class TxListener { constructor (opt, executionContext) { this.event = new EventManager() - // has a default for now for backwards compatability + // has a default for now for backwards compatibility this.executionContext = executionContext this._api = opt.api this._resolvedTransactions = {} diff --git a/libs/remix-lib/src/execution/txRunnerVM.ts b/libs/remix-lib/src/execution/txRunnerVM.ts index 5a800e2326b..31364c045a7 100644 --- a/libs/remix-lib/src/execution/txRunnerVM.ts +++ b/libs/remix-lib/src/execution/txRunnerVM.ts @@ -34,7 +34,7 @@ export class TxRunnerVM { constructor (vmaccounts, api, getVMObject) { this.event = new EventManager() this.logsManager = new LogsManager() - // has a default for now for backwards compatability + // has a default for now for backwards compatibility this.getVMObject = getVMObject this.commonContext = this.getVMObject().common this.blockNumber = 0 diff --git a/libs/remix-ui/debugger-ui/src/lib/api/debugger-api.ts b/libs/remix-ui/debugger-ui/src/lib/api/debugger-api.ts index 34fc44ed7e3..0879471fe83 100644 --- a/libs/remix-ui/debugger-ui/src/lib/api/debugger-api.ts +++ b/libs/remix-ui/debugger-ui/src/lib/api/debugger-api.ts @@ -163,7 +163,7 @@ export const DebuggerApiMixin = (Base) => class extends Base { else this._web3 = this.initialWeb3 init.extendWeb3(this._web3) if (this.onDebugRequestedListener) { - this.onDebugRequestedListener(hash, web3).then((debuggerBackend) => { + this.onDebugRequestedListener(hash, this._web3).then((debuggerBackend) => { this.debuggerBackend = debuggerBackend }) } diff --git a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css index 628182ece16..c1b6cae8603 100644 --- a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css +++ b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.css @@ -2,26 +2,7 @@ display: flex; flex-wrap: wrap; } -.stepButtons { - width: 100%; - display: flex; - justify-content: center; - align-items: center; - color: #fff; -} -.stepButton { -} -.stepButtonDisabled { - background-color: #005573; - border-color: #005573; -} - -.stepButton:hover { - color: #fff; - background-color: var(--primary); - border-color: #005573; -} .jumpButtons { width: 100%; display: flex; @@ -29,23 +10,6 @@ align-items: center; color: #fff; } -.jumpButton { -} - -.jumpButtonDisabled { - background-color: var(--grey); - border-color: #005573; -} - -.jumButton:hover { - color: #fff; - background-color: #005573; - border-color: #005573; -} -.navigator { -} -.navigator:hover { -} .cursorPointerRemixDebugger { cursor: pointer; diff --git a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx index a050280d2f7..5609280eed5 100644 --- a/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx +++ b/libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx @@ -66,13 +66,11 @@ export const ButtonNavigation = ({ } const stepBtnStyle = 'd-flex align-items-center justify-content-center btn btn-primary btn-sm stepButton h-75 m-0 p-1' - const disableStepBtnStyle = 'stepButtonDisabled' - const disableJumpBtnStyle = 'jumpButtonDisabled' const stepMarkupStructure = { stepOverBackJSX: { markup: (
{ stepOverBack && stepOverBack() }} @@ -97,7 +95,7 @@ export const ButtonNavigation = ({ stepBackJSX: { markup: (
{ stepIntoBack && stepIntoBack() }} @@ -126,7 +124,7 @@ export const ButtonNavigation = ({ stepIntoJSX: { markup: (
{ stepIntoForward && stepIntoForward() }} @@ -154,7 +152,7 @@ export const ButtonNavigation = ({ stepOverForwardJSX: { markup: (
{ stepOverForward && stepOverForward() }} @@ -183,7 +181,7 @@ export const ButtonNavigation = ({ jumpPreviousBreakpointJSX: { markup: (
{ jumpPreviousBreakpoint && jumpPreviousBreakpoint() @@ -191,7 +189,7 @@ export const ButtonNavigation = ({ data-id="buttonNavigatorJumpPreviousBreakpoint" >