From 842aa08f7c0bcb3cc39bdd0b97048ee2d2e94ff0 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Tue, 26 Jul 2022 19:09:01 +0530 Subject: [PATCH 01/67] save file with .yul extension if language is yul in URL --- libs/remix-ui/workspace/src/lib/actions/workspace.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 37533c87c6..221e0e1a09 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -75,7 +75,8 @@ export const createWorkspaceTemplate = async (workspaceName: string, template: W export type UrlParametersType = { gist: string, code: string, - url: string + url: string, + language: string } export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDefault') => { @@ -91,7 +92,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe if (params.code) { const hash = bufferToHex(keccakFromString(params.code)) - path = 'contract-' + hash.replace('0x', '').substring(0, 10) + '.sol' + path = 'contract-' + hash.replace('0x', '').substring(0, 10) + (params.language && params.language.toLowerCase() === 'yul' ? '.yul': '.sol') content = atob(params.code) await workspaceProvider.set(path, content) } From 1c0ad8084299db972cb32d6d82a1336c76702db9 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Tue, 26 Jul 2022 19:30:23 +0530 Subject: [PATCH 02/67] e2e added --- apps/remix-ide-e2e/src/tests/url.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apps/remix-ide-e2e/src/tests/url.test.ts b/apps/remix-ide-e2e/src/tests/url.test.ts index 00885338b4..2d7554215e 100644 --- a/apps/remix-ide-e2e/src/tests/url.test.ts +++ b/apps/remix-ide-e2e/src/tests/url.test.ts @@ -76,6 +76,22 @@ module.exports = { .openFile('ethereum/remix-project/apps/remix-ide/contracts/app/solidity/mode.sol') }, + 'Should load the code from language & code params': function (browser: NightwatchBrowser) { + browser + .pause(5000) + .url('http://127.0.0.1:8080/#language=yul&version=soljson-v0.8.7+commit.e28d00a7.js&code=Ly8gQSBjb250cmFjdCBjb25zaXN0cyBvZiBhIHNpbmdsZSBvYmplY3Qgd2l0aCBzdWItb2JqZWN0cyByZXByZXNlbnRpbmcKLy8gdGhlIGNvZGUgdG8gYmUgZGVwbG95ZWQgb3Igb3RoZXIgY29udHJhY3RzIGl0IGNhbiBjcmVhdGUuCi8vIFRoZSBzaW5nbGUgImNvZGUiIG5vZGUgaXMgdGhlIGV4ZWN1dGFibGUgY29kZSBvZiB0aGUgb2JqZWN0LgovLyBFdmVyeSAob3RoZXIpIG5hbWVkIG9iamVjdCBvciBkYXRhIHNlY3Rpb24gaXMgc2VyaWFsaXplZCBhbmQKLy8gbWFkZSBhY2Nlc3NpYmxlIHRvIHRoZSBzcGVjaWFsIGJ1aWx0LWluIGZ1bmN0aW9ucyBkYXRhY29weSAvIGRhdGFvZmZzZXQgLyBkYXRhc2l6ZQovLyBUaGUgY3VycmVudCBvYmplY3QsIHN1Yi1vYmplY3RzIGFuZCBkYXRhIGl0ZW1zIGluc2lkZSB0aGUgY3VycmVudCBvYmplY3QKLy8gYXJlIGluIHNjb3BlLgpvYmplY3QgIkNvbnRyYWN0MSIgewogICAgLy8gVGhpcyBpcyB0aGUgY29uc3RydWN0b3IgY29kZSBvZiB0aGUgY29udHJhY3QuCiAgICBjb2RlIHsKICAgICAgICBmdW5jdGlvbiBhbGxvY2F0ZShzaXplKSAtPiBwdHIgewogICAgICAgICAgICBwdHIgOj0gbWxvYWQoMHg0MCkKICAgICAgICAgICAgaWYgaXN6ZXJvKHB0cikgeyBwdHIgOj0gMHg2MCB9CiAgICAgICAgICAgIG1zdG9yZSgweDQwLCBhZGQocHRyLCBzaXplKSkKICAgICAgICB9CgogICAgICAgIC8vIGZpcnN0IGNyZWF0ZSAiQ29udHJhY3QyIgogICAgICAgIGxldCBzaXplIDo9IGRhdGFzaXplKCJDb250cmFjdDIiKQogICAgICAgIGxldCBvZmZzZXQgOj0gYWxsb2NhdGUoc2l6ZSkKICAgICAgICAvLyBUaGlzIHdpbGwgdHVybiBpbnRvIGNvZGVjb3B5IGZvciBFVk0KICAgICAgICBkYXRhY29weShvZmZzZXQsIGRhdGFvZmZzZXQoIkNvbnRyYWN0MiIpLCBzaXplKQogICAgICAgIC8vIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBpcyBhIHNpbmdsZSBudW1iZXIgMHgxMjM0CiAgICAgICAgbXN0b3JlKGFkZChvZmZzZXQsIHNpemUpLCAweDEyMzQpCiAgICAgICAgcG9wKGNyZWF0ZShvZmZzZXQsIGFkZChzaXplLCAzMiksIDApKQoKICAgICAgICAvLyBub3cgcmV0dXJuIHRoZSBydW50aW1lIG9iamVjdCAodGhlIGN1cnJlbnRseQogICAgICAgIC8vIGV4ZWN1dGluZyBjb2RlIGlzIHRoZSBjb25zdHJ1Y3RvciBjb2RlKQogICAgICAgIHNpemUgOj0gZGF0YXNpemUoIkNvbnRyYWN0MV9kZXBsb3llZCIpCiAgICAgICAgb2Zmc2V0IDo9IGFsbG9jYXRlKHNpemUpCiAgICAgICAgLy8gVGhpcyB3aWxsIHR1cm4gaW50byBhIG1lbW9yeS0+bWVtb3J5IGNvcHkgZm9yIEV3YXNtIGFuZAogICAgICAgIC8vIGEgY29kZWNvcHkgZm9yIEVWTQogICAgICAgIGRhdGFjb3B5KG9mZnNldCwgZGF0YW9mZnNldCgiQ29udHJhY3QxX2RlcGxveWVkIiksIHNpemUpCiAgICAgICAgcmV0dXJuKG9mZnNldCwgc2l6ZSkKICAgIH0KCiAgICBkYXRhICJUYWJsZTIiIGhleCI0MTIzIgoKICAgIG9iamVjdCAiQ29udHJhY3QxX2RlcGxveWVkIiB7CiAgICAgICAgY29kZSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGFsbG9jYXRlKHNpemUpIC0+IHB0ciB7CiAgICAgICAgICAgICAgICBwdHIgOj0gbWxvYWQoMHg0MCkKICAgICAgICAgICAgICAgIGlmIGlzemVybyhwdHIpIHsgcHRyIDo9IDB4NjAgfQogICAgICAgICAgICAgICAgbXN0b3JlKDB4NDAsIGFkZChwdHIsIHNpemUpKQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBydW50aW1lIGNvZGUKCiAgICAgICAgICAgIG1zdG9yZSgwLCAiSGVsbG8sIFdvcmxkISIpCiAgICAgICAgICAgIHJldHVybigwLCAweDIwKQogICAgICAgIH0KICAgIH0KCiAgICAvLyBFbWJlZGRlZCBvYmplY3QuIFVzZSBjYXNlIGlzIHRoYXQgdGhlIG91dHNpZGUgaXMgYSBmYWN0b3J5IGNvbnRyYWN0LAogICAgLy8gYW5kIENvbnRyYWN0MiBpcyB0aGUgY29kZSB0byBiZSBjcmVhdGVkIGJ5IHRoZSBmYWN0b3J5CiAgICBvYmplY3QgIkNvbnRyYWN0MiIgewogICAgICAgIGNvZGUgewogICAgICAgICAgICAvLyBjb2RlIGhlcmUgLi4uCiAgICAgICAgfQoKICAgICAgICBvYmplY3QgIkNvbnRyYWN0Ml9kZXBsb3llZCIgewogICAgICAgICAgICBjb2RlIHsKICAgICAgICAgICAgICAgIC8vIGNvZGUgaGVyZSAuLi4KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZGF0YSAiVGFibGUxIiBoZXgiNDEyMyIKICAgIH0KfQ&optimize=false&runs=200&evmVersion=null') + .refresh() + .pause(5000) + .clickLaunchIcon('filePanel') + .currentWorkspaceIs('code-sample') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontract-eaa022e37e.yul"]', 6000) + .openFile('contract-eaa022e37e.yul') + .getEditorValue((content) => { + browser.assert.ok(content && content.indexOf( + 'object "Contract1" {') !== -1) + }) + }, + 'Should load using URL compiler params': function (browser: NightwatchBrowser) { browser .pause(5000) From e7fdf9aa19e79154587bf7bf8db04a2824ef48dd Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Tue, 26 Jul 2022 14:15:24 +0530 Subject: [PATCH 03/67] allow yul deployment --- libs/remix-core-plugin/src/lib/compiler-metadata.ts | 2 +- libs/remix-core-plugin/src/lib/editor-context-listener.ts | 2 +- libs/remix-ui/run-tab/src/lib/actions/events.ts | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libs/remix-core-plugin/src/lib/compiler-metadata.ts b/libs/remix-core-plugin/src/lib/compiler-metadata.ts index 2f065e769f..9a69e616f4 100644 --- a/libs/remix-core-plugin/src/lib/compiler-metadata.ts +++ b/libs/remix-core-plugin/src/lib/compiler-metadata.ts @@ -87,7 +87,7 @@ export class CompilerMetadata extends Plugin { let parsedMetadata try { - parsedMetadata = JSON.parse(contract.object.metadata) + parsedMetadata = contract.object && contract.object.metadata ? JSON.parse(contract.object.metadata) : null } catch (e) { console.log(e) } diff --git a/libs/remix-core-plugin/src/lib/editor-context-listener.ts b/libs/remix-core-plugin/src/lib/editor-context-listener.ts index 6fd5674e8a..3785c8ffd1 100644 --- a/libs/remix-core-plugin/src/lib/editor-context-listener.ts +++ b/libs/remix-core-plugin/src/lib/editor-context-listener.ts @@ -92,7 +92,7 @@ export class EditorContextListener extends Plugin { this._stopHighlighting() this.currentPosition = cursorPosition this.currentFile = file - if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) { + if (compilationResult && compilationResult.data && compilationResult.data.sources && compilationResult.data.sources[file]) { const nodes = sourceMappingDecoder.nodesAtPosition(null, cursorPosition, compilationResult.data.sources[file]) this.nodes = nodes if (nodes && nodes.length && nodes[nodes.length - 1]) { diff --git a/libs/remix-ui/run-tab/src/lib/actions/events.ts b/libs/remix-ui/run-tab/src/lib/actions/events.ts index 4355f4e87e..e47724aef0 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/events.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/events.ts @@ -95,7 +95,6 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch) => { const broadcastCompilationResult = async (plugin: RunTab, dispatch: React.Dispatch, file, source, languageVersion, data, input?) => { // TODO check whether the tab is configured const compiler = new CompilerAbstract(languageVersion, data, source, input) - plugin.compilersArtefacts[languageVersion] = compiler plugin.compilersArtefacts.__last = compiler @@ -103,9 +102,8 @@ const broadcastCompilationResult = async (plugin: RunTab, dispatch: React.Dispat return { name: languageVersion, alias: contract.name, file: contract.file, compiler } }) const index = contracts.findIndex(contract => contract.alias === plugin.REACT_API.contracts.currentContract) - if ((index < 0) && (contracts.length > 0)) dispatch(setCurrentContract(contracts[0].alias)) - const isUpgradeable = await plugin.call('openzeppelin-proxy', 'isConcerned', data.sources[file] ? data.sources[file].ast : {}) + const isUpgradeable = await plugin.call('openzeppelin-proxy', 'isConcerned', data.sources && data.sources[file] ? data.sources[file].ast : {}) if (isUpgradeable) { const options = await plugin.call('openzeppelin-proxy', 'getProxyOptions', data, file) From ad54a0c5d80aa81498caeb68130a3378cee210ff Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Tue, 26 Jul 2022 18:50:39 +0530 Subject: [PATCH 04/67] e2e tests added --- apps/remix-ide-e2e/src/tests/ballot.test.ts | 36 +++++++++++++++++++ .../src/lib/compiler-container.tsx | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/ballot.test.ts b/apps/remix-ide-e2e/src/tests/ballot.test.ts index 1c8383f047..04fd37077f 100644 --- a/apps/remix-ide-e2e/src/tests/ballot.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot.test.ts @@ -134,6 +134,27 @@ module.exports = { .sendKeys('*[data-id$="scConfigFilePathInput"]', browser.Keys.ENTER) .openFile('Untitled.sol') .verifyContracts(['Ballot'], {wait: 2000, runs: '300'}) + }, + + 'Compile and deploy sample yul file': function (browser: NightwatchBrowser) { + browser + .addFile('sample.yul', {content: yulSample}) + .clickLaunchIcon('solidity') + .waitForElementVisible('*[data-id="scConfigExpander"]') + .click('*[data-id="scManualConfiguration"]') + .waitForElementVisible('select[id="compilierLanguageSelector"]', 10000) + .click('select[id="compilierLanguageSelector"]') + .click('select[id="compilierLanguageSelector"] option[value=Yul]') + .waitForElementContainsText('[data-id="compiledContracts"]', 'Contract', 60000) + .clickLaunchIcon('udapp') + .click('*[data-id="Deploy - transact (not payable)"]') + .waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]', 60000) + .testFunction('last', + { + status: 'true Transaction mined and execution succeed', + to: 'Contract.(constructor)' + }) + .pause(3000) .end() } } @@ -387,4 +408,19 @@ const configFile = ` "evmVersion": "byzantium" } } +` + +const yulSample = ` +object "Contract" { + code { + function power(base, exponent) -> result + { + result := 1 + for { let i := 0 } lt(i, exponent) { i := add(i, 1) } + { + result := mul(result, base) + } + } + } +} ` \ No newline at end of file diff --git a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx index 80d5e88e9f..34613067a2 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx @@ -765,7 +765,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
- +
From 15de89b71aecda654389c05f3f17e2f67a20b414 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Wed, 27 Jul 2022 12:30:36 +0530 Subject: [PATCH 05/67] e2e fix --- apps/remix-ide-e2e/src/tests/ballot.test.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/ballot.test.ts b/apps/remix-ide-e2e/src/tests/ballot.test.ts index 04fd37077f..fc090988e1 100644 --- a/apps/remix-ide-e2e/src/tests/ballot.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot.test.ts @@ -149,12 +149,8 @@ module.exports = { .clickLaunchIcon('udapp') .click('*[data-id="Deploy - transact (not payable)"]') .waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]', 60000) - .testFunction('last', - { - status: 'true Transaction mined and execution succeed', - to: 'Contract.(constructor)' - }) - .pause(3000) + .journalLastChildIncludes('Contract.(constructor)') + .journalLastChildIncludes('data: 0x602...0565b') .end() } } From fd18da31504f5b8bf77908229d5ca67c2dcfc4a7 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Wed, 27 Jul 2022 13:43:11 +0530 Subject: [PATCH 06/67] bump remixd --- libs/remixd/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remixd/package.json b/libs/remixd/package.json index 9cee73f6e9..f46b7c0d97 100644 --- a/libs/remixd/package.json +++ b/libs/remixd/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remixd", - "version": "0.6.4", + "version": "0.6.5", "description": "remix server: allow accessing file system from remix.ethereum.org and start a dev environment (see help section)", "main": "index.js", "types": "./index.d.ts", From c0fb88e8c733665d9f306c0713f382fb4b0be5eb Mon Sep 17 00:00:00 2001 From: David Disu Date: Mon, 25 Jul 2022 15:09:58 +0100 Subject: [PATCH 07/67] Enable deploy with proxy url params --- .../src/lib/constants/uups.ts | 3 +- .../src/lib/openzeppelin-proxy.ts | 52 +++++++++++-------- .../src/lib/components/contractGUI.tsx | 22 +++++--- 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/libs/remix-core-plugin/src/lib/constants/uups.ts b/libs/remix-core-plugin/src/lib/constants/uups.ts index 606d62dd77..66d28acc59 100644 --- a/libs/remix-core-plugin/src/lib/constants/uups.ts +++ b/libs/remix-core-plugin/src/lib/constants/uups.ts @@ -102,4 +102,5 @@ export const UUPSupgradeAbi = { "outputs": [], "stateMutability": "nonpayable", "type": "function" -} \ No newline at end of file +} +export const EnableProxyURLParam = 'deployProxy' \ No newline at end of file diff --git a/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts b/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts index ef03092cb8..25aa04c91e 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 { UUPS, UUPSABI, UUPSBytecode, UUPSfunAbi, UUPSupgradeAbi } from './constants/uups' +import { EnableProxyURLParam, UUPS, UUPSABI, UUPSBytecode, UUPSfunAbi, UUPSupgradeAbi } from './constants/uups' const proxyProfile = { name: 'openzeppelin-proxy', @@ -33,31 +33,39 @@ export class OpenZeppelinProxy extends Plugin { async getProxyOptions (data: ContractSources, file: string): Promise<{ [name: string]: DeployOptions }> { const contracts = data.contracts[file] const ast = data.sources[file].ast - const inputs = {} if (this.kind === 'UUPS') { - Object.keys(contracts).map(name => { - if (ast) { - const UUPSSymbol = ast.exportedSymbols[UUPS] ? ast.exportedSymbols[UUPS][0] : null - - ast.absolutePath === file && ast.nodes.map((node) => { - if (node.name === name && node.linearizedBaseContracts.includes(UUPSSymbol)) { - const abi = contracts[name].abi - const initializeInput = abi.find(node => node.name === 'initialize') - - inputs[name] = { - options: [{ title: 'Deploy with Proxy', active: false }, { title: 'Upgrade with Proxy', active: false }], - initializeOptions: { - inputs: initializeInput, - initializeInputs: initializeInput ? this.blockchain.getInputs(initializeInput) : null - } + const options = await (this.getUUPSContractOptions(contracts, ast, file)) + + return options + } + } + + 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 + + options[name] = { + options: [{ title: 'Deploy with Proxy', active: isDeployWithProxyEnabled }, { title: 'Upgrade with Proxy', active: false }], + initializeOptions: { + inputs: initializeInput, + initializeInputs: initializeInput ? this.blockchain.getInputs(initializeInput) : null } } - }) - } - }) - } - return inputs + } + })) + } + })) + return options } async executeUUPSProxy(implAddress: string, args: string | string [] = '', initializeABI, implementationContractObject): Promise { diff --git a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx index 7fe409e511..9cc5b061b2 100644 --- a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx @@ -24,6 +24,16 @@ export function ContractGUI (props: ContractGUIProps) { const initializeFields = useRef>([]) const basicInputRef = useRef() + useEffect(() => { + if (props.deployOption && Array.isArray(props.deployOption)) { + if (props.deployOption[0] && props.deployOption[0].title === 'Deploy with Proxy') { + handleDeployProxySelect(props.deployOption[0].active) + } else if (props.deployOption[1] && props.deployOption[1].title === 'Deploy with Proxy') { + handleUpgradeImpSelect(props.deployOption[1].active) + } + } + }, [props.deployOption]) + useEffect(() => { if (props.title) { setTitle(props.title) @@ -179,9 +189,7 @@ export function ContractGUI (props: ContractGUIProps) { setToggleDeployProxy(!toggleDeployProxy) } - const handleDeployProxySelect = (e) => { - const value = e.target.checked - + const handleDeployProxySelect = (value: boolean) => { if (value) setToggleUpgradeImp(false) setToggleDeployProxy(value) setDeployState({ upgrade: false, deploy: value }) @@ -191,9 +199,7 @@ export function ContractGUI (props: ContractGUIProps) { setToggleUpgradeImp(!toggleUpgradeImp) } - const handleUpgradeImpSelect = (e) => { - const value = e.target.checked - + const handleUpgradeImpSelect = (value: boolean) => { setToggleUpgradeImp(value) if (value) { setToggleDeployProxy(false) @@ -264,7 +270,7 @@ export function ContractGUI (props: ContractGUIProps) { data-id="contractGUIDeployWithProxy" className="form-check-input custom-control-input" type="checkbox" - onChange={handleDeployProxySelect} + onChange={(e) => handleDeployProxySelect(e.target.checked)} checked={deployState.deploy} />