Merge branch 'master' of https://github.com/ethereum/remix-project into terminalwrapper

pull/4551/head
bunsenstraat 11 months ago
commit 7491afa8d4
  1. 4
      .github/workflows/pr-reminder.yml
  2. 2
      Dockerfile.dev
  3. 2
      apps/circuit-compiler/src/app/services/circomPluginClient.ts
  4. 2
      apps/circuit-compiler/src/snarkjs.min.js
  5. 4
      apps/remix-ide-e2e/package.json
  6. 32
      apps/remix-ide-e2e/src/commands/checkTerminalFilter.ts
  7. 2
      apps/remix-ide-e2e/src/commands/getLastTransactionHash.ts
  8. 8
      apps/remix-ide-e2e/src/commands/journalChildIncludes.ts
  9. 6
      apps/remix-ide-e2e/src/examples/example-contracts.ts
  10. 2
      apps/remix-ide-e2e/src/tests/ballot.test.ts
  11. 2
      apps/remix-ide-e2e/src/tests/ballot_0_4_14.test.ts
  12. 10
      apps/remix-ide-e2e/src/tests/compiler_api.test.ts
  13. 2
      apps/remix-ide-e2e/src/tests/publishContract.test.ts
  14. 2
      apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts
  15. 24
      apps/remix-ide-e2e/src/tests/transactionExecution.test.ts
  16. 40
      apps/remix-ide-e2e/src/tests/url.test.ts
  17. 4
      apps/remix-ide-e2e/src/tests/verticalIconsPanel.test.ts
  18. 2
      apps/remix-ide-e2e/src/tests/vyper_api.test.ts
  19. 2
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  20. 4
      apps/remix-ide-e2e/src/tests/workspace_git.test.ts
  21. 2
      apps/remix-ide-e2e/src/types/index.d.ts
  22. 28
      apps/remix-ide-e2e/yarn.lock
  23. 2
      apps/remix-ide/Dockerfile.dev
  24. 4
      apps/remix-ide/ci/sauceDisconnect.js
  25. 2
      apps/remix-ide/contracts/foundry/out/Script.sol/Script.json
  26. 8
      apps/remix-ide/meetings.md
  27. 9
      apps/remix-ide/src/app/editor/editor.js
  28. 4
      apps/remix-ide/src/app/files/dgitProvider.ts
  29. 10
      apps/remix-ide/src/app/files/fileManager.ts
  30. 2
      apps/remix-ide/src/app/plugins/code-format.ts
  31. 2
      apps/remix-ide/src/app/plugins/compile-details.tsx
  32. 2
      apps/remix-ide/src/app/plugins/file-decorator.ts
  33. 2
      apps/remix-ide/src/app/plugins/parser/services/code-parser-compiler.ts
  34. 4
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  35. 2
      apps/remix-ide/src/app/tabs/locales/en/permissionHandler.json
  36. 2
      apps/remix-ide/src/app/tabs/locales/en/publishToStorage.json
  37. 2
      apps/remix-ide/src/app/tabs/locales/en/remixUiTabs.json
  38. 2
      apps/remix-ide/src/app/tabs/locales/en/search.json
  39. 3
      apps/remix-ide/src/app/tabs/locales/en/settings.json
  40. 4
      apps/remix-ide/src/app/tabs/locales/en/solidity.json
  41. 2
      apps/remix-ide/src/app/tabs/locales/en/terminal.json
  42. 13
      apps/remix-ide/src/app/tabs/locales/en/udapp.json
  43. 2
      apps/remix-ide/src/app/tabs/locales/es/filePanel.json
  44. 2
      apps/remix-ide/src/app/tabs/locales/fr/filePanel.json
  45. 2
      apps/remix-ide/src/app/tabs/locales/it/filePanel.json
  46. 2
      apps/remix-ide/src/app/tabs/locales/zh/filePanel.json
  47. 2
      apps/remix-ide/src/app/tabs/network-module.js
  48. 6
      apps/remix-ide/src/app/tabs/runTab/model/recorder.js
  49. 2
      apps/remix-ide/src/app/tabs/styles/settings-tab-styles.js
  50. 2
      apps/remix-ide/src/app/tabs/theme-module.js
  51. 10
      apps/remix-ide/src/app/udapp/run-tab.js
  52. 6
      apps/remix-ide/src/assets/js/parser/antlr.js
  53. 2
      apps/remix-ide/src/assets/js/parser/antlr.js.map
  54. 4
      apps/remix-ide/src/blockchain/blockchain.tsx
  55. 2
      apps/remixdesktop/src/menus/darwin.ts
  56. 39
      apps/remixdesktop/yarn.lock
  57. 40
      apps/vyper/src/app/app.css
  58. 67
      apps/vyper/src/app/app.tsx
  59. 23
      apps/vyper/src/app/components/CompileErrorCard.tsx
  60. 2
      apps/vyper/src/app/components/CompilerButton.tsx
  61. 26
      apps/vyper/src/app/components/CustomAccordionToggle.tsx
  62. 2
      apps/vyper/src/app/components/VyperResult.tsx
  63. 174
      apps/vyper/src/app/utils/compiler.tsx
  64. 13
      apps/vyper/src/app/utils/remix-client.tsx
  65. 4
      apps/vyper/src/index.html
  66. 4
      apps/vyper/src/profile.json
  67. 8
      libs/ghaction-helper/package.json
  68. 8
      libs/remix-analyzer/package.json
  69. 10
      libs/remix-analyzer/src/solidity-analyzer/modules/abstractAstView.ts
  70. 6
      libs/remix-analyzer/src/solidity-analyzer/modules/checksEffectsInteraction.ts
  71. 6
      libs/remix-analyzer/src/solidity-analyzer/modules/constantFunctions.ts
  72. 6
      libs/remix-analyzer/src/solidity-analyzer/modules/functionCallGraph.ts
  73. 4
      libs/remix-analyzer/src/solidity-analyzer/modules/noReturn.ts
  74. 4
      libs/remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts
  75. 16
      libs/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts
  76. 2
      libs/remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.ts
  77. 2
      libs/remix-analyzer/src/types.ts
  78. 8
      libs/remix-analyzer/test/analysis/staticAnalysisCommon-test.ts
  79. 6
      libs/remix-astwalker/package.json
  80. 1
      libs/remix-core-plugin/src/index.ts
  81. 8
      libs/remix-core-plugin/src/lib/compiler-content-imports.ts
  82. 10
      libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts
  83. 5
      libs/remix-core-plugin/src/lib/gist-handler.ts
  84. 67
      libs/remix-core-plugin/src/lib/helpers/fetch-blockscout.ts
  85. 16
      libs/remix-core-plugin/src/lib/offset-line-to-column-converter.ts
  86. 12
      libs/remix-debug/package.json
  87. 4
      libs/remix-debug/src/code/codeResolver.ts
  88. 4
      libs/remix-debug/src/solidity-decoder/decodeInfo.ts
  89. 2
      libs/remix-debug/src/solidity-decoder/solidityProxy.ts
  90. 16
      libs/remix-debug/src/source/offsetToLineColumnConverter.ts
  91. 2
      libs/remix-debug/src/storage/mappingPreimages.ts
  92. 4
      libs/remix-debug/src/storage/storageResolver.ts
  93. 2
      libs/remix-debug/src/trace/traceCache.ts
  94. 2
      libs/remix-debug/test.ts
  95. 4
      libs/remix-lib/package.json
  96. 4
      libs/remix-lib/src/execution/txExecution.ts
  97. 20
      libs/remix-lib/src/execution/txFormat.ts
  98. 2
      libs/remix-lib/src/execution/txListener.ts
  99. 2
      libs/remix-lib/src/execution/txRunnerWeb3.ts
  100. 2
      libs/remix-lib/src/hash.ts
  101. Some files were not shown because too many files have changed in this diff Show More

@ -2,7 +2,7 @@ name: PRs reviews reminder
on:
schedule:
- cron: "0 8-17/8 * * 1-5"
- cron: "0 8 * * 1-5"
workflow_dispatch:
jobs:
@ -14,4 +14,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
freeze-date: '2024-02-26T18:00:00Z'
freeze-date: '2024-03-11T18:00:00Z'

@ -1,4 +1,4 @@
# This dockerfile is to build each branch seperately (for dev purposes)
# This dockerfile is to build each branch separately (for dev purposes)
FROM node:10
# Create Remix user, don't use root!
# RUN yes | adduser --disabled-password remix && mkdir /app

@ -298,7 +298,7 @@ export class CircomPluginClient extends PluginClient {
}
} else {
if (depPath) {
// resolves relative dependecies for .deps folder
// resolves relative dependencies for .deps folder
path = pathModule.resolve(depPath.slice(0, depPath.lastIndexOf('/')), include)
path = path.replace('https:/', 'https://')
if (path.indexOf('/') === 0) path = path.slice(1)

File diff suppressed because one or more lines are too long

@ -6,8 +6,8 @@
"npm": "^6.14.15"
},
"dependencies": {
"@openzeppelin/contracts": "^5.0.0",
"@openzeppelin/contracts-upgradeable": "^5.0.0",
"@openzeppelin/contracts": "^5.0.2",
"@openzeppelin/contracts-upgradeable": "^5.0.2",
"@openzeppelin/upgrades-core": "^1.30.0",
"@openzeppelin/wizard": "^0.4.0",
"@remix-project/remixd": "../../dist/libs/remixd",

@ -2,9 +2,9 @@ import EventEmitter from 'events'
import { NightwatchBrowser } from 'nightwatch'
class CheckTerminalFilter extends EventEmitter {
command (this: NightwatchBrowser, filter: string, test: string): NightwatchBrowser {
command (this: NightwatchBrowser, filter: string, test: string, notContain: boolean): NightwatchBrowser {
this.api.perform((done) => {
checkFilter(this.api, filter, test, () => {
checkFilter(this.api, filter, test, notContain, () => {
done()
this.emit('complete')
})
@ -13,20 +13,30 @@ class CheckTerminalFilter extends EventEmitter {
}
}
function checkFilter (browser: NightwatchBrowser, filter: string, test: string, done: VoidFunction) {
if (browser.options.desiredCapabilities.browserName === 'chrome') { // nightwatch deos not handle well that part.... works locally
function checkFilter (browser: NightwatchBrowser, filter: string, inputTest: string, notContain: boolean, done: VoidFunction) {
/*if (browser.options.desiredCapabilities.browserName === 'chrome') { // nightwatch deos not handle well that part.... works locally
done()
return
}
const filterClass = '[data-id="terminalInputSearch"]'
browser.setValue(filterClass, filter, function () {
}*/
const filterClass = '[data-id="terminalInputSearchTerminal"]'
browser.clearValue(filterClass).setValue(filterClass, filter, function () {
browser.execute(function () {
return document.querySelector('[data-id="terminalJournal"]').innerHTML === test || ''
return document.querySelector('[data-id="terminalJournal"]').innerHTML
}, [], function (result) {
browser.clearValue(filterClass).setValue(filterClass, '', function () {
if (!result.value) {
browser.assert.fail('useFilter on ' + filter + ' ' + test, 'info about error', '')
console.log(notContain, result.value, filter)
if (!notContain) {
// the input text should be contained in the result
if ((result.value as string).indexOf(filter) === -1) {
browser.assert.fail('useFilter on ' + filter + ' ' + test, 'the input text should be contained in the result', '')
}
}
if (notContain) {
// the input text should not be contained in the result
if ((result.value as string).indexOf(filter) !== -1) {
browser.assert.fail('useFilter on ' + filter + ' ' + test, 'the input text should not be contained in the result', '')
}
}
browser.clearValue(filterClass).perform(() => {
done()
})
})

@ -15,7 +15,7 @@ class GetLastTransactionHash extends EventEmitter {
}
function getLastTransactionHash (browser: NightwatchBrowser, callback: (hash: string) => void) {
browser.waitForElementPresent('*[data-shared="universalDappUiInstance"]')
browser.waitForElementPresent('*[data-id="terminalJournal"]')
.execute(function () {
const deployedContracts = document.querySelectorAll('*[data-id="terminalJournal"] > div')
for (let i = deployedContracts.length - 1; i >= 0; i--) {

@ -5,10 +5,10 @@ import EventEmitter from 'events'
Checks if any child elements of journal (console) contains a matching value.
*/
class JournalChildIncludes extends EventEmitter {
command (this: NightwatchBrowser, val: string, opts = { shouldHaveOnlyOneOccurence: false }): NightwatchBrowser {
command (this: NightwatchBrowser, val: string, opts = { shouldHaveOnlyOneOccurrence: false }): NightwatchBrowser {
let isTextFound = false
const browser = this.api
let occurence = 0
let occurrence = 0
this.api.elements('css selector', '*[data-id="terminalJournal"]', (res) => {
Array.isArray(res.value) && res.value.forEach(function (jsonWebElement) {
const jsonWebElementId = jsonWebElement[ELEMENT_KEY] || jsonWebElement[Object.keys(jsonWebElement)[0]]
@ -18,14 +18,14 @@ class JournalChildIncludes extends EventEmitter {
if (typeof text === 'string' && text.indexOf(val) !== -1) {
isTextFound = true
occurence++
occurrence++
}
})
})
})
browser.perform(() => {
browser.assert.ok(isTextFound, isTextFound ? `<*[data-id="terminalJournal"]> contains ${val}.` : `${val} not found in <*[data-id="terminalJournal"]> div:last-child>`)
if (opts.shouldHaveOnlyOneOccurence) browser.assert.ok(occurence === 1, `${occurence} occurence found of "${val}"`)
if (opts.shouldHaveOnlyOneOccurrence) browser.assert.ok(occurrence === 1, `${occurrence} occurrence found of "${val}"`)
this.emit('complete')
})
return this

@ -4,7 +4,7 @@ const storage = `pragma solidity >=0.7.0 <0.9.0;
/**
* @title Storage
* @dev Store & retreive value in a variable
* @dev Store & retrieve value in a variable
*/
contract Storage {
@ -22,7 +22,7 @@ contract Storage {
* @dev Return value
* @return value of 'number'
*/
function retreive() public view returns (uint256){
function retrieve() public view returns (uint256){
return number;
}
}`
@ -301,7 +301,7 @@ contract BallotTest {
Assert.equal(ballotToTest.winnerName(), bytes32("candidate1"), "candidate1 should be the winner name");
}
function checkWinninProposalWithReturnValue () public view returns (bool) {
function checkWinningProposalWithReturnValue () public view returns (bool) {
return ballotToTest.winningProposal() == 0;
}
}

@ -75,7 +75,7 @@ module.exports = {
abortOnFailure: false,
suppressNotFoundErrors: true,
})
// we are not changing the visibility for not checksumed contracts
// we are not changing the visibility for not checksummed contracts
// .addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3B', true, false)
.clickLaunchIcon('filePanel')
.addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3A', true, true)

@ -71,7 +71,7 @@ module.exports = {
abortOnFailure: false,
suppressNotFoundErrors: true,
})
// we are not changing the visibility for not checksumed contracts
// we are not changing the visibility for not checksummed contracts
// .addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3B', true, false)
.clickLaunchIcon('filePanel')
.addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3A', true, true)

@ -18,7 +18,7 @@ module.exports = {
return sources
},
'Should compile using "compileWithParamaters" API #group1': function (browser: NightwatchBrowser) {
'Should compile using "compileWithParameters" API #group1': function (browser: NightwatchBrowser) {
browser
.addFile('test_jsCompile.js', { content: jsCompile })
.executeScriptInTerminal('remix.exeCurrent()')
@ -26,7 +26,7 @@ module.exports = {
.click('*[data-id="terminalClearConsole"]')
},
'Should compile using "compileWithParamaters" API with optimization On #group2': function (browser: NightwatchBrowser) {
'Should compile using "compileWithParameters" API with optimization On #group2': function (browser: NightwatchBrowser) {
browser
.addFile('test_jsCompileWithOptimization.js', { content: jsCompileWithOptimization })
.executeScriptInTerminal('remix.exeCurrent()')
@ -34,7 +34,7 @@ module.exports = {
.click('*[data-id="terminalClearConsole"]')
},
'Should compile using "compileWithParamaters" API with optimization off check default runs #group3': function (browser: NightwatchBrowser) {
'Should compile using "compileWithParameters" API with optimization off check default runs #group3': function (browser: NightwatchBrowser) {
browser
.addFile('test_jsCompileWithOptimizationDefault.js', { content: jsCompileWithOptimizationDefault })
.executeScriptInTerminal('remix.exeCurrent()')
@ -65,7 +65,7 @@ const simpleContract = `pragma solidity >=0.4.22 <0.9.1;
/**
* @title Storage
* @dev Store & retreive value in a variable
* @dev Store & retrieve value in a variable
*/
contract StorageTestUpdateConfiguration {
@ -83,7 +83,7 @@ contract StorageTestUpdateConfiguration {
* @dev Return value
* @return value of 'number'
*/
function retreive() public view returns (uint256){
function retrieve() public view returns (uint256){
return number;
}
}

@ -38,7 +38,7 @@ module.exports = {
.openFile('ipfs/QmXYUS1ueS22EqNVRaKuZa31EgHLjKZ8uTM8vWhQLxa3pw')
},
/* Disableing the test untill refactoring and the new swarm usage
/* Disabling the test until refactoring and the new swarm usage
'Publish on Swarm': '' + function (browser: NightwatchBrowser) {
browser
.click('#publishOnSwarm')

@ -202,7 +202,7 @@ module.exports = {
},
/*
* This test is using 3 differents services:
* This test is using 3 different services:
* - Metamask for getting the transaction
* - Source Verifier service for fetching the contract code
* - Ropsten node for retrieving the trace and storage

@ -42,7 +42,7 @@ module.exports = {
.clickLaunchIcon('udapp')
.click('.udapp_contractActionsContainerSingle > div')
.clickInstance(0)
.clickFunction('retunValues1 - transact (not payable)')
.clickFunction('returnValues1 - transact (not payable)')
.testFunction('last',
{
status: '0x1 Transaction mined and execution succeed',
@ -53,7 +53,7 @@ module.exports = {
3: 'address: _a 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c'
}
})
.clickFunction('retunValues2 - transact (not payable)')
.clickFunction('returnValues2 - transact (not payable)')
.testFunction('last',
{
status: '0x1 Transaction mined and execution succeed',
@ -70,7 +70,7 @@ module.exports = {
9: 'bytes32: _b32 0x0325235325325235325235325235320000000000000000000000000000000000'
}
}).pause(500)
.clickFunction('retunValues3 - transact (not payable)')
.clickFunction('returnValues3 - transact (not payable)')
.testFunction('last',
{
status: '0x1 Transaction mined and execution succeed',
@ -150,6 +150,14 @@ module.exports = {
.click('*[data-id="deployAndRunClearInstances"]')
},
'Should filter displayed transactions #group2': function (browser: NightwatchBrowser) {
browser
// it should contain: 0xd9145CCE52D386f254917e481eB44e9943F39138
.checkTerminalFilter('0xd9145CCE52D386f254917e481eB44e9943F39138', '0xd9145CCE52D386f254917e481eB44e9943F39138', false)
// it should not contain: 0xd9145CCE52D386f254917e481eB44e9943F39140 (it ends with 40)
.checkTerminalFilter('0xd9145CCE52D386f254917e481eB44e9943F39140', '0xd9145CCE52D386f254917e481eB44e9943F39138', true)
},
'Should Compile and Deploy a contract which define a custom error, the error should be logged in the terminal #group3': function (browser: NightwatchBrowser) {
browser.testContracts('customError.sol', sources[4]['customError.sol'], ['C'])
.clickLaunchIcon('udapp')
@ -312,10 +320,10 @@ const sources = [
contract TestContract { function f() public returns (uint) { return 8; }
function g() public returns (uint, string memory, bool, uint) {
uint payment = 345;
bool payed = true;
bool paid = true;
string memory comment = "comment_comment_";
uint month = 4;
return (payment, comment, payed, month); } }`
return (payment, comment, paid, month); } }`
}
},
{
@ -323,14 +331,14 @@ const sources = [
content: `
contract testReturnValues {
enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }
function retunValues1 () public returns (bool _b, uint _u, int _i, address _a) {
function returnValues1 () public returns (bool _b, uint _u, int _i, address _a) {
_b = true;
_u = 345;
_i = -345;
_a = msg.sender;
}
function retunValues2 () public returns (bytes1 _b, bytes2 _b2, bytes3 _b3, bytes memory _blit, bytes5 _b5, bytes6 _b6, string memory _str, bytes7 _b7, bytes22 _b22, bytes32 _b32) {
function returnValues2 () public returns (bytes1 _b, bytes2 _b2, bytes3 _b3, bytes memory _blit, bytes5 _b5, bytes6 _b6, string memory _str, bytes7 _b7, bytes22 _b22, bytes32 _b32) {
_b = 0x12;
_b2 = 0x1223;
_b5 = hex"043245";
@ -342,7 +350,7 @@ const sources = [
_str = "this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string _ this is a long string";
}
function retunValues3 () public returns (ActionChoices _en, int[5][] memory _a1) {
function returnValues3 () public returns (ActionChoices _en, int[5][] memory _a1) {
_en = ActionChoices.GoStraight;
int[5][] memory a = new int[5][](3);
a[0] = [int(1),-45,-78,56,60];

@ -107,6 +107,46 @@ module.exports = {
})
},
'Should load Blockscout verified contracts from URL "address" and "blockscout" params (single source)': function (browser: NightwatchBrowser) {
browser
.url('http://127.0.0.1:8080/#address=0xdAC17F958D2ee523a2206206994597C13D831ec7&blockscout=eth.blockscout.com')
.refreshPage()
.pause(7000)
.currentWorkspaceIs('code-sample')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0xdAC17F958D2ee523a2206206994597C13D831ec7"]')
.getEditorValue((content) => {
browser.assert.ok(content && content.indexOf(
'contract TetherToken is Pausable, StandardToken, BlackList {') !== -1)
})
},
'Should load Blockscout verified contracts from URL "address" and "blockscout" params (multiple sources)': function (browser: NightwatchBrowser) {
browser
.url('http://127.0.0.1:8080/#address=0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9&blockscout=eth.blockscout.com')
.refreshPage()
.pause(7000)
.currentWorkspaceIs('code-sample')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts/open-zeppelin"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts/open-zeppelin/Address.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts/open-zeppelin/BaseAdminUpgradeabilityProxy.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts/open-zeppelin/BaseUpgradeabilityProxy.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts/open-zeppelin/InitializableAdminUpgradeabilityProxy.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts/open-zeppelin/InitializableUpgradeabilityProxy.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts/open-zeppelin/Proxy.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemeth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts/open-zeppelin/UpgradeabilityProxy.sol"]')
.openFile('eth.blockscout.com/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/contracts/open-zeppelin/InitializableAdminUpgradeabilityProxy.sol')
.getEditorValue((content) => {
browser.assert.ok(content && content.indexOf(
'contract InitializableAdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, InitializableUpgradeabilityProxy {') !== -1)
})
},
'Should load the code from URL & code params #group1': function (browser: NightwatchBrowser) {
browser
.url('http://127.0.0.1:8080/#optimize=true&runs=300&url=https://github.com/ethereum/remix-project/blob/master/apps/remix-ide/contracts/app/solidity/mode.sol&code=cHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuNy4wOwoKaW1wb3J0ICJodHRwczovL2dpdGh1Yi5jb20vT3BlblplcHBlbGluL29wZW56ZXBwZWxpbi1jb250cmFjdHMvYmxvYi9tYXN0ZXIvY29udHJhY3RzL2FjY2Vzcy9Pd25hYmxlLnNvbCI7Cgpjb250cmFjdCBHZXRQYWlkIGlzIE93bmFibGUgewogIGZ1bmN0aW9uIHdpdGhkcmF3KCkgZXh0ZXJuYWwgb25seU93bmVyIHsKICB9Cn0')

@ -7,7 +7,7 @@ module.exports = {
init(browser, done, 'http://127.0.0.1:8080', false)
},
'Checks vertical icons panelcontex menu': function (browser: NightwatchBrowser) {
'Checks vertical icons panel context menu': function (browser: NightwatchBrowser) {
browser.waitForElementVisible('div[data-id="remixIdeIconPanel"]', 10000)
.waitForElementVisible('*[data-id="verticalIconsKindpluginManager"]')
.click('*[data-id="verticalIconsKindpluginManager"]')
@ -19,7 +19,7 @@ module.exports = {
.click('*[data-id="remixIdeIconPanel"]')
},
'Checks vertical icons panel contex menu deactivate': function (browser: NightwatchBrowser) {
'Checks vertical icons panel context menu deactivate': function (browser: NightwatchBrowser) {
browser.waitForElementVisible('div[data-id="remixIdeIconPanel"]', 10000)
.waitForElementVisible('*[data-id="verticalIconsKinddebugger"]', 7000)
.pause(5000)

@ -67,7 +67,6 @@ module.exports = {
browser
// @ts-ignore
.frame(0)
.click('[data-id="remote-compiler"]')
.click('[data-id="compile"]')
.waitForElementVisible({
selector:'[data-id="compilation-details"]',
@ -89,7 +88,6 @@ module.exports = {
chromeBrowser.setPermission('clipboard-write', 'granted')
browser
.frame(0)
.click('[data-id="remote-compiler"]')
.click('[data-id="compile"]')
.waitForElementVisible({
selector:'[data-id="compilation-details"]',

@ -501,7 +501,7 @@ module.exports = {
.pause(2000)
},
'Should change the current workspace in localstorage to a non existant value, reload the page and see the workspace created #group2': function (browser: NightwatchBrowser) {
'Should change the current workspace in localstorage to a non existent value, reload the page and see the workspace created #group2': function (browser: NightwatchBrowser) {
browser
.execute(function () {
localStorage.setItem('currentWorkspace', 'non_existing_workspace')

@ -209,7 +209,7 @@ module.exports = {
.expect.element('[data-id="workspaceGit-newLocalBranch"]').text.to.contain('✓ ')
},
'Should checkout to an exisiting local branch #group3': function (browser: NightwatchBrowser) {
'Should checkout to an existing local branch #group3': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('[data-id="custom-dropdown-menu"]')
.waitForElementPresent('[data-id="workspaceGitInput"]')
@ -239,7 +239,7 @@ module.exports = {
.expect.element('[data-id="workspaceGit-main"]').text.to.contain('✓ ')
},
'Should force checkout to a branch with exisiting local changes #group3': function (browser: NightwatchBrowser) {
'Should force checkout to a branch with existing local changes #group3': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('[data-id="workspaceGit-dev"]')
.click('[data-id="workspaceGit-dev"]')

@ -54,7 +54,7 @@ declare module 'nightwatch' {
notContainsText(cssSelector: string, text: string): NightwatchBrowser
sendLowLevelTx(address: string, value: string, callData: string): NightwatchBrowser
journalLastChild(val: string): NightwatchBrowser
checkTerminalFilter(filter: string, test: string): NightwatchBrowser
checkTerminalFilter(filter: string, test: string, notContain: boolean): NightwatchBrowser
noWorkerErrorFor(version: string): NightwatchBrowser
validateValueInput(selector: string, valueTosSet: string[], expectedValue: string): NightwatchBrowser
checkAnnotations(type: string): NightwatchBrowser

@ -14,15 +14,15 @@
pathval "1.1.1"
type-detect "4.0.8"
"@openzeppelin/contracts-upgradeable@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.0.tgz#859c00c55f04b6dda85b3c88bce507d65019888f"
integrity sha512-D54RHzkOKHQ8xUssPgQe2d/U92mwaiBDY7qCCVGq6VqwQjsT3KekEQ3bonev+BLP30oZ0R1U6YC8/oLpizgC5Q==
"@openzeppelin/contracts-upgradeable@^5.0.2":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz#3e5321a2ecdd0b206064356798c21225b6ec7105"
integrity sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ==
"@openzeppelin/contracts@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.0.tgz#ee0e4b4564f101a5c4ee398cd4d73c0bd92b289c"
integrity sha512-bv2sdS6LKqVVMLI5+zqnNrNU/CA+6z6CmwFXm/MzmOPBRSO5reEJN7z0Gbzvs0/bv/MZZXNklubpwy3v2+azsw==
"@openzeppelin/contracts@^5.0.2":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.2.tgz#b1d03075e49290d06570b2fd42154d76c2a5d210"
integrity sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==
"@openzeppelin/upgrades-core@^1.30.0":
version "1.30.1"
@ -1910,14 +1910,14 @@ internal-slot@^1.0.5:
side-channel "^1.0.4"
ip@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48"
integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==
version "1.1.9"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.9.tgz#8dfbcc99a754d07f425310b86a99546b1151e396"
integrity sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==
ip@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
is-accessor-descriptor@^0.1.6:
version "0.1.6"

@ -1,4 +1,4 @@
# This dockerfile is to build each branch seperately (for dev purpouses)
# This dockerfile is to build each branch separately (for dev purpouses)
FROM node:10
# Create Remix user, don't use root!
# RUN yes | adduser --disabled-password remix && mkdir /app

@ -18,7 +18,7 @@ function removeTunnel () {
retrieveTunnel(data[k], function (error, result) {
if (error) {
console.log(error)
} else if (result.identtifier === tunnelName) {
} else if (result.identifier === tunnelName) {
deleteTunnel(result.id, function () {
console.log('tunnel deleted ' + data[k] + ' ' + tunnelName)
})
@ -35,7 +35,7 @@ function retrieveTunnel (tunnelid, callback) {
if (error) {
callback(error)
} else {
callback(null, {'identtifier': JSON.parse(result).tunnel_identifier, 'id': tunnelid})
callback(null, {'identifier': JSON.parse(result).tunnel_identifier, 'id': tunnelid})
}
})
}

@ -3355,7 +3355,7 @@
"id": 1818,
"nodeType": "StructuredDocumentation",
"src": "361:227:1",
"text": "@dev Compute the address a contract will be deployed at for a given deployer address and nonce\n @notice adapated from Solmate implementation (https://github.com/transmissions11/solmate/blob/main/src/utils/LibRLP.sol)"
"text": "@dev Compute the address a contract will be deployed at for a given deployer address and nonce\n @notice adapted from Solmate implementation (https://github.com/transmissions11/solmate/blob/main/src/utils/LibRLP.sol)"
},
"implemented": true,
"kind": "function",

@ -21,8 +21,8 @@ we move the documentation to the remix-ide repository
## medium post policy
Any post that relates to Ethereum could be put in the remix plublication.
Although that is not mandatory and left up to the writter.
Any post that relates to Ethereum could be put in the remix publication.
Although that is not mandatory and left up to the writer.
## guided tour
@ -32,7 +32,7 @@ It will work as a native plugin, started by default.
Each other native plugin can request a guided tour with:
`this.call('guidedtour', 'start', 'debugger')`
Other type of plugin may be able to the native plugin guided tour but we won't push this if the integration is not working out of the box.
We rather update the remix-plugin doc saying that `guided tour framework name` is the prefferred one.
We rather update the remix-plugin doc saying that `guided tour framework name` is the preferred one.
## web site
@ -49,7 +49,7 @@ it will be set of file:
- solidity contract
- test contract
we only support md for now and move to supporting other format if needded.
we only support md for now and move to supporting other format if needed.
It requires the "test" native plugin to extend its API.
@rob/@francois are managing that.

@ -52,7 +52,8 @@ class Editor extends Plugin {
cairo: 'cairo',
ts: 'typescript',
move: 'move',
circom: 'circom'
circom: 'circom',
nr: 'rust'
}
this.activated = false
@ -360,7 +361,7 @@ class Editor extends Plugin {
/**
* Path of the currently editing file
* returns `undefined` if no session is being editer
* returns `undefined` if no session is being edited
* @return {String} path of the current session
*/
current () {
@ -449,7 +450,7 @@ class Editor extends Plugin {
}
/**
* Clears all the decorations for the given @arg filePath and @arg plugin, if none is given, the current sesssion is used.
* Clears all the decorations for the given @arg filePath and @arg plugin, if none is given, the current session is used.
* An annotation has the following shape:
column: -1
row: -1
@ -502,7 +503,7 @@ class Editor extends Plugin {
}
/**
* Clears all the annotations for the given @arg filePath, the plugin name is retrieved from the context, if none is given, the current sesssion is used.
* Clears all the annotations for the given @arg filePath, the plugin name is retrieved from the context, if none is given, the current session is used.
* An annotation has the following shape:
column: -1
row: -1

@ -577,7 +577,7 @@ class DGitProvider extends Plugin {
dir
})
} catch (e) {
this.call('terminal', 'log', { type: 'error', value: `[Cloning]: Error occured! ${e}` })
this.call('terminal', 'log', { type: 'error', value: `[Cloning]: Error occurred! ${e}` })
console.log(e)
}
}
@ -587,7 +587,7 @@ class DGitProvider extends Plugin {
}, 1000)
}
} catch (e) {
this.call('terminal', 'log', { type: 'error', value: `[Cloning]: Error occured! ${e}` })
this.call('terminal', 'log', { type: 'error', value: `[Cloning]: Error occurred! ${e}` })
// do nothing
}
}

@ -24,7 +24,7 @@ const profile = {
methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'writeMultipleFiles', 'writeFileNoRewrite',
'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'dirList', 'fileList', 'remove', 'getCurrentFile', 'getFile',
'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath',
'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory', 'hasGitSubmodule'
'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory', 'hasGitSubmodule', 'copyFolderToJson'
],
kind: 'file-system'
}
@ -1041,6 +1041,14 @@ class FileManager extends Plugin {
throw new Error(e)
}
}
async copyFolderToJson(folder: string) {
const provider = this.currentFileProvider()
if (provider && provider.copyFolderToJson) {
return await provider.copyFolderToJson(folder)
}
throw new Error('copyFolderToJson not available')
}
}
module.exports = FileManager

@ -9,7 +9,7 @@ import { filePathFilter, AnyFilter } from '@jsdevtools/file-path-filter'
const profile = {
name: 'codeFormatter',
desciption: 'prettier plugin for Remix',
description: 'prettier plugin for Remix',
methods: ['format'],
events: [''],
version: '0.0.1'

@ -45,7 +45,7 @@ export class CompilationDetailsPlugin extends ViewPlugin {
async showDetails(sentPayload: any) {
await this.call('tabs', 'focus', 'compilationDetails')
setTimeout(() => {
// TODO: use the react API to render when the tab is focused and tbe plugin in the view.
// TODO: use the react API to render when the tab is focused and the plugin in the view.
this.payload = sentPayload
this.renderComponent()
}, 2000)

@ -7,7 +7,7 @@ import { fileDecoration } from '@remix-ui/file-decorators'
const profile = {
name: 'fileDecorator',
desciption: 'Keeps decorators of the files',
description: 'Keeps decorators of the files',
methods: ['setFileDecorators', 'clearFileDecorators', 'clearAllFileDecorators'],
events: ['fileDecoratorsChanged'],
version: '0.0.1'

@ -35,7 +35,7 @@ type errorMarker = {
}
export default class CodeParserCompiler {
plugin: CodeParser
compiler: any // used to compile the current file seperately from the main compiler
compiler: any // used to compile the current file separately from the main compiler
onAstFinished: (success: any, data: CompilationResult, source: CompilationSourceCode, input: any, version: any) => Promise<void>;
errorState: boolean;
gastEstimateTimeOut: any

@ -34,6 +34,8 @@
"filePanel.tssoltestghaction": "Mocha Chai Test Workflow",
"filePanel.workspace.addscriptetherscan": "Adds scripts which can be used to interact with the Etherscan API",
"filePanel.addscriptetherscan": "Add Etherscan scripts",
"filePanel.workspace.addscriptsindri": "Adds scripts for interacting with Sindri, a zk proof generation remote service",
"filePanel.addscriptsindri": "Add Sindri ZK scripts",
"filePanel.workspace.addscriptdeployer": "Adds scripts which can be used to deploy contracts",
"filePanel.addscriptdeployer": "Add contract deployer scripts",
"filePanel.workspace.slitherghaction": "Adds a preset yml file to run slither analysis on github actions CI",
@ -94,7 +96,7 @@
"filePanel.copyFolderFailed": "Copy Folder Failed",
"filePanel.copyFolderFailedMsg": "Unexpected error while copying folder: {src}",
"filePanel.runScriptFailed": "Run script failed",
"filePanel.createPublicGist": "Create a public gist",
"filePanel.createPublicGist": "Publish to a public gist",
"filePanel.createPublicGistMsg1": "Are you sure you want to push changes to remote gist file on github.com?",
"filePanel.createPublicGistMsg2": "Are you sure you want to anonymously publish all your files in the {path} folder as a public gist on github.com?",
"filePanel.createPublicGistMsg3": "Are you sure you want to anonymously publish {path} file as a public gist on github.com?",

@ -1,5 +1,5 @@
{
"permissionHandler.allPermissionsReset": "All permisssions have been reset.",
"permissionHandler.allPermissionsReset": "All permissions have been reset.",
"permissionHandler.rememberText": "has changed and",
"permissionHandler.permissionHandlerMessage": "\"{from}\" {rememberText} would like to access to \"{method}\" of \"{to}\"`",
"permissionHandler.description": "Description",

@ -10,7 +10,7 @@
"publishToStorage.title4.message3": "Instead of that, 4 options are now available:",
"publishToStorage.title4.message4": "DEFAULT OPTION: Use the public INFURA node. This will not guarantee your data will persist.",
"publishToStorage.title4.message5": "Use your own INFURA IPFS node. This requires a subscription. <a>Learn more</a>",
"publishToStorage.title4.message6": "Use any external IPFS which doesn’t require any authentification.",
"publishToStorage.title4.message6": "Use any external IPFS which doesn’t require any authentication.",
"publishToStorage.title4.message7": "Use your own local ipfs node (which usually runs under http://localhost:5001)",
"publishToStorage.title4.message8": "You can update your IPFS settings in the SETTINGS tab.",
"publishToStorage.title4.message9": "Now the default option will be used.",

@ -1,7 +1,7 @@
{
"remixUiTabs.tooltipText1": "Run script (CTRL + SHIFT + S)",
"remixUiTabs.tooltipText2": "Compile CTRL + S",
"remixUiTabs.tooltipText3": "Select .sol or .yul file to compile or a .ts or .js file and run it",
"remixUiTabs.tooltipText3": "Select .sol, .vy or .yul file to compile or a .ts or .js file and run it",
"remixUiTabs.zoomOut": "Zoom out",
"remixUiTabs.zoomIn": "Zoom in"
}

@ -20,5 +20,5 @@
"search.no": "No",
"search.loading": "Loading",
"search.text1": "showing {count} results in {fileCount} files",
"search.text2": "Too many resuls to display...{br}Please narrow down your search."
"search.text2": "Too many results to display...{br}Please narrow down your search."
}

@ -17,6 +17,9 @@
"settings.etherscanTokenTitle": "EtherScan Access Token",
"settings.etherscanAccessTokenText": "Manage the api key used to interact with Etherscan.",
"settings.etherscanAccessTokenText2": "Go to Etherscan api key page (link below) to create a new api key and save it in Remix.",
"settings.sindriAccessTokenTitle": "Sindri Credentials",
"settings.sindriAccessTokenText": "The access token is used to compile ZKP circuits and generate proofs with Sindri.",
"settings.sindriAccessTokenText2":"Go to the Sindri account creation page (link below) to create a new token and save it in Remix.",
"settings.save": "Save",
"settings.remove": "Remove",
"settings.themes": "Themes",

@ -46,7 +46,7 @@
"solidity.compileIconAttribute": "compiler is loading, please wait a few moments.",
"solidity.compilerLicense": "Compiler License",
"solidity.compilerLicenseMsg1": "Compiler is loading. License will be displayed once compiler is loaded",
"solidity.compilerLicenseMsg2": "Could not retreive license for selected compiler version",
"solidity.compilerLicenseMsg2": "Could not retrieve license for selected compiler version",
"solidity.compilerLicenseMsg3": "License not available",
"solidity.seeCompilerLicense": "See compiler license",
@ -69,7 +69,7 @@
"solidity.Assembly": "Assembly opcodes describing the contract including corresponding solidity source code",
"solidity.Opcodes": "Assembly opcodes describing the contract",
"solidity.name": "Name of the compiled contract",
"solidity.metadata": "Contains all informations related to the compilation",
"solidity.metadata": "Contains all information related to the compilation",
"solidity.bytecode": "Bytecode being executed during contract creation",
"solidity.abi": "ABI: describing all the functions (input/output params, scope, ...)",
"solidity.web3Deploy": "Copy/paste this code to any JavaScript/Web3 console to deploy this contract",

@ -15,7 +15,7 @@
"terminal.welcomeText8": "Right click on a JavaScript file in the file explorer and then click `Run`",
"terminal.welcomeText9": "The following libraries are accessible",
"terminal.welcomeText10": "Type the library name to see available commands",
"terminal.text1": "This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.",
"terminal.text1": "This type of command has been deprecated and is not functioning anymore. Please run remix.help() to list available commands.",
"terminal.hideTerminal": "Hide Terminal",
"terminal.showTerminal": "Show Terminal",
"terminal.clearConsole": "Clear console",

@ -26,7 +26,7 @@
"udapp.contractOptionsTitle2": "Select a compiled contract to deploy or to use with At Address.",
"udapp.contractOptionsTitle3": "Select and compile *.sol file to deploy or access a contract.",
"udapp.contractOptionsTitle4": "When there is a compiled .sol file, choose the contract to deploy or to use with At Address.",
"udapp.checkSumWarning": "It seems you are not using a checksumed address.A checksummed address is an address that contains uppercase letters, as specified in {a}.Checksummed addresses are meant to help prevent users from sending transactions to the wrong address.",
"udapp.checkSumWarning": "It seems you are not using a checksummed address. A checksummed address is an address that contains uppercase letters, as specified in {a}. Checksummed addresses are meant to help prevent users from sending transactions to the wrong address.",
"udapp.isOverSizePromptEip170": "Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fail if the current network has activated the eip 170. More info: {a}",
"udapp.isOverSizePromptEip3860": "Contract creation init code exceeds the allowed max code size of 49152 bytes. The deployment will likely fail if the current network has activated the eip 3860. More info: {a}",
"udapp.thisContractMayBeAbstract": "This contract may be abstract, it may not implement an abstract parent's methods completely or it may not invoke an inherited contract's constructor correctly.",
@ -67,9 +67,15 @@
"udapp._comment_instanceContainerUI.tsx": "libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx",
"udapp.deployedContracts": "Deployed Contracts",
"udapp.deployAndRunClearInstances": "Clear instances list and reset recorder",
"udapp.deployAndRunNoInstanceText": "Currently you have no contract instances to interact with.",
"udapp.deployAndRunNoInstanceText": "Currently you have no deployed contracts to interact with.",
"udapp.tooltipText6": "Autogenerated generic user interfaces for interaction with deployed contracts",
"udapp.savedContracts": "Saved Contracts",
"udapp.NoSavedInstanceText": "No saved contracts found.",
"udapp.tooltipTextUnsave": "Unsave & move to Deployed Contracts list",
"udapp.savedOn": "Saved On",
"udapp.filePath": "File Path",
"udapp._comment_recorderCardUI.tsx": "libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx",
"udapp.transactionsRecorded": "Transactions recorded",
"udapp.transactionsCountTooltip": "The number of recorded transactions",
@ -99,6 +105,7 @@
"udapp._comment_universalDappUI.tsx": "libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx",
"udapp.tooltipText7": "Remove from the list",
"udapp.tooltipText14": "Save & move to Saved Contracts list",
"udapp.tooltipText8": "Click for docs about using 'receive'/'fallback'",
"udapp.tooltipText9": "The Calldata to send to fallback function of the contract.",
"udapp.tooltipText10": "Send data to contract.",
@ -123,7 +130,7 @@
"udapp.contractCreation": "Contract Creation",
"udapp.transactionFee": "Transaction is invalid. Max fee should not be less than Base fee",
"udapp.title1": "Represents the part of the tx fee that goes to the miner.",
"udapp.title2": "Represents the maximum amount of fee that you will pay for this transaction. The minimun needs to be set to base fee.",
"udapp.title2": "Represents the maximum amount of fee that you will pay for this transaction. The minimum needs to be set to base fee.",
"udapp.gasPrice": "Gas price",
"udapp.gweiText": "visit {a} for current gas price info.",
"udapp.maxTransactionFee": "Max transaction fee",

@ -86,7 +86,7 @@
"filePanel.copyFolderFailed": "Copia de Carpeta Fallida",
"filePanel.copyFolderFailedMsg": "Error inesperado al copiar la carpeta: {src}",
"filePanel.runScriptFailed": "Error al ejecutar el script",
"filePanel.createPublicGist": "Crear una lista pública",
"filePanel.createPublicGist": "Publicar una lista pública",
"filePanel.createPublicGistMsg1": "¿Está seguro que desea empujar cambios al archivo gist remoto en github.com?",
"filePanel.createPublicGistMsg2": "¿Estás seguro que quieres publicar todos tus archivos de forma anónima en la carpeta {path} como un gist público en github.com?",
"filePanel.createPublicGistMsg3": "¿Estás seguro de que quieres publicar de forma anónima el archivo {path} como una gist público en github.com?",

@ -86,7 +86,7 @@
"filePanel.copyFolderFailed": "Échec de la copie du dossier",
"filePanel.copyFolderFailedMsg": "Erreur inattendue lors de la copie du fichier : {src}",
"filePanel.runScriptFailed": "Échec de l'exécution du script",
"filePanel.createPublicGist": "Créer un gist public",
"filePanel.createPublicGist": "Publier un gist public",
"filePanel.createPublicGistMsg1": "Êtes-vous sûr de vouloir envoyer les changements dans le fichier gist distant sur github.com?",
"filePanel.createPublicGistMsg2": "Êtes-vous sûr de vouloir publier anonymement tous vos fichiers dans le dossier {path} en tant que gist public sur github.com?",
"filePanel.createPublicGistMsg3": "Êtes-vous sûr de vouloir publier anonymement tous vos fichiers dans le dossier {path} en tant que gist public sur github.com?",

@ -86,7 +86,7 @@
"filePanel.copyFolderFailed": "Copia Cartella Non Riuscita",
"filePanel.copyFolderFailedMsg": "Errore inatteso durante la copia della cartella: {src}",
"filePanel.runScriptFailed": "Esecuzione dello script non riuscita",
"filePanel.createPublicGist": "Crea Gist Pubblico",
"filePanel.createPublicGist": "Pubblicare Gist Pubblico",
"filePanel.createPublicGistMsg1": "Sei sicuro di voler inviare le modifiche al file gist remoto su github.com?",
"filePanel.createPublicGistMsg2": "Sei sicuro di voler pubblicare in modo anonimo tutti i tuoi file nella cartella {path} come gist pubblico su github.com?",
"filePanel.createPublicGistMsg3": "Sei sicuro di voler pubblicare in modo anonimo tutti i tuoi file nella cartella {path} come gist pubblico su github.com?",

@ -86,7 +86,7 @@
"filePanel.copyFolderFailed": "复制文件夹失败",
"filePanel.copyFolderFailedMsg": "复制文件夹时出现意外错误:{src}",
"filePanel.runScriptFailed": "执行脚本失败",
"filePanel.createPublicGist": "创建一个公开的 gist",
"filePanel.createPublicGist": "发布到公共 gist",
"filePanel.createPublicGistMsg1": "您确定要将更改推送到 github.com 上的远程 gist 文件吗?",
"filePanel.createPublicGistMsg2": "您确定要在 github.com 上以匿名方式将 {path} 文件夹中的所有文件发布为公开的 gist?",
"filePanel.createPublicGistMsg3": "您确定要将 {path} 文件匿名发布为 github.com 上的公开 gist?",

@ -20,7 +20,7 @@ export class NetworkModule extends Plugin {
super(profile)
this.blockchain = blockchain
// TODO: See with remix-lib to make sementic coherent
// TODO: See with remix-lib to make semantic coherent
this.blockchain.event.register('contextChanged', (provider) => {
this.emit('providerChanged', provider)
})

@ -84,7 +84,7 @@ class Recorder extends Plugin {
const rawAddress = txResult.receipt.contractAddress
if (!rawAddress) return // not a contract creation
const address = addressToString(rawAddress)
// save back created addresses for the conversion from tokens to real adresses
// save back created addresses for the conversion from tokens to real addresses
this.data._createdContracts[address] = timestamp
this.data._createdContractsReverse[timestamp] = address
})
@ -98,7 +98,7 @@ class Recorder extends Plugin {
}
/**
* stop/start saving txs. If not listenning, is basically in replay mode
* stop/start saving txs. If not listening, is basically in replay mode
*
* @param {Bool} listen
*/
@ -279,7 +279,7 @@ class Recorder extends Plugin {
}
if (rawAddress) {
const address = addressToString(rawAddress)
// save back created addresses for the conversion from tokens to real adresses
// save back created addresses for the conversion from tokens to real addresses
this.data._createdContracts[address] = tx.timestamp
this.data._createdContractsReverse[tx.timestamp] = address
newContractFn(abi, address, record.contractName)

@ -29,7 +29,7 @@ const css = csjs`
.heading {
margin-bottom: 0;
}
.explaination {
.explanation {
margin-top: 3px;
margin-bottom: 3px;
}

@ -146,7 +146,7 @@ export class ThemeModule extends Plugin {
}
/**
* fixes the invertion for images since this should be adjusted when we switch between dark/light qualified themes
* fixes the inversion for images since this should be adjusted when we switch between dark/light qualified themes
* @param {element} [image] - the dom element which invert should be fixed to increase visibility
*/
fixInvert(image) {

@ -28,7 +28,9 @@ const profile = {
'getSettings',
'setEnvironmentMode',
'clearAllInstances',
'clearAllSavedInstances',
'addInstance',
'addSavedInstance',
'resolveContractAndAddInstance'
]
}
@ -79,10 +81,18 @@ export class RunTab extends ViewPlugin {
this.emit('clearAllInstancesReducer')
}
clearAllSavedInstances() {
this.emit('clearAllSavedInstancesReducer')
}
addInstance(address, abi, name) {
this.emit('addInstanceReducer', address, abi, name)
}
addSavedInstance(address, abi, name, savedOn, filePath) {
this.emit('addSavedInstanceReducer', address, abi, name, savedOn, filePath)
}
createVMAccount(newAccount) {
return this.blockchain.createVMAccount(newAccount)
}

@ -21298,9 +21298,9 @@ var SolidityParser = (() => {
Dependents2[Dependents2["ANCESTORS"] = 3] = "ANCESTORS";
Dependents2[Dependents2["DESCENDANTS"] = 4] = "DESCENDANTS";
Dependents2[Dependents2["SIBLINGS"] = 5] = "SIBLINGS";
Dependents2[Dependents2["PRECEEDING_SIBLINGS"] = 6] = "PRECEEDING_SIBLINGS";
Dependents2[Dependents2["PRECEDING_SIBLINGS"] = 6] = "PRECEDING_SIBLINGS";
Dependents2[Dependents2["FOLLOWING_SIBLINGS"] = 7] = "FOLLOWING_SIBLINGS";
Dependents2[Dependents2["PRECEEDING"] = 8] = "PRECEEDING";
Dependents2[Dependents2["PRECEDING"] = 8] = "PRECEDING";
Dependents2[Dependents2["FOLLOWING"] = 9] = "FOLLOWING";
})(Dependents = exports.Dependents || (exports.Dependents = {}));
}
@ -33949,7 +33949,7 @@ var SolidityParser = (() => {
_toText(ctx) {
const text = ctx.text;
if (text === void 0) {
throw new Error("Assertion error: text should never be undefiend");
throw new Error("Assertion error: text should never be undefined");
}
return text;
}

File diff suppressed because one or more lines are too long

@ -526,7 +526,7 @@ export class Blockchain extends Plugin {
}
/**
* return the fork name applied to the current envionment
* return the fork name applied to the current environment
* @return {String} - fork name
*/
getCurrentFork() {
@ -619,7 +619,7 @@ export class Blockchain extends Plugin {
return this.executionContext.isVM() ? 'memory' : 'blockchain'
}
// NOTE: the config is only needed because exectuionContext.init does
// NOTE: the config is only needed because executionContext.init does
async resetAndInit(config: Config, transactionContextAPI: TransactionContextAPI) {
this.transactionContextAPI = transactionContextAPI
this.executionContext.init(config)

@ -1,4 +1,4 @@
// This menu label is overrided by OSX to be the appName
// This menu label is overridden by OSX to be the appName
// The label is set to appName here so it matches actual behavior
import {app, BrowserWindow, MenuItemConstructorOptions} from 'electron';

@ -520,9 +520,9 @@
semver "^7.3.5"
"@openzeppelin/contracts@^4.7.3":
version "4.9.3"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364"
integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==
version "4.9.6"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.6.tgz#2a880a24eb19b4f8b25adc2a5095f2aa27f39677"
integrity sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==
"@openzeppelin/wizard@^0.1.1":
version "0.1.1"
@ -2173,13 +2173,14 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es5-ext@^0.10.35, es5-ext@^0.10.50:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@^0.10.62, es5-ext@~0.10.14:
version "0.10.63"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.63.tgz#9c222a63b6a332ac80b1e373b426af723b895bd6"
integrity sha512-hUCZd2Byj/mNKjfP9jXrdVZ62B8KuA/VoK7X8nUh5qT+AxDmcbvZz041oDVZdbIN1qW6XY9VDNwzkvKnZvK2TQ==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-error@^4.1.1:
@ -2224,6 +2225,16 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
@ -2351,6 +2362,14 @@ ethjs-unit@0.1.6:
bn.js "4.11.6"
number-to-bn "1.7.0"
event-emitter@^0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==
dependencies:
d "1"
es5-ext "~0.10.14"
eventemitter3@4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384"
@ -3083,9 +3102,9 @@ internal-slot@^1.0.5:
side-channel "^1.0.4"
ip@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
ipaddr.js@1.9.1:
version "1.9.1"

@ -222,3 +222,43 @@ html, body, #root, main {
margin: 15px;
padding: 15px;
}
.cursor-status {
}
.cursor-status :hover {
cursor: pointer;
}
.accordion-background {
background-color: var(--body-bg);
}
.accordion-background:hover {
cursor: pointer;
}
.vyper-compile-warning,
.vyper-compile-error {
white-space: pre-line;
word-wrap: break-word;
cursor: pointer;
position: relative;
margin: 0.5em 0 1em 0;
border-radius: 5px;
line-height: 20px;
padding: 8px 15px;
}
.vyper-compile-warning pre,
.vyper-compile-error pre {
white-space: pre-line;
overflow-y: hidden;
background-color: transparent;
margin: 0;
font-size: 12px;
border: 0 none;
padding: 0;
border-radius: 0;
}

@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react'
import React, {useState, useEffect, useRef} from 'react'
import {remixClient} from './utils'
import {CompilationResult} from '@remixproject/plugin-api'
@ -11,11 +11,14 @@ import LocalUrlInput from './components/LocalUrl'
import ToggleButtonGroup from 'react-bootstrap/ToggleButtonGroup'
import ToggleButton from 'react-bootstrap/ToggleButton'
import Button from 'react-bootstrap/Button'
import Accordion from 'react-bootstrap/Accordion'
import Card from 'react-bootstrap/Card'
import './app.css'
import {CustomTooltip} from '@remix-ui/helper'
import {Form} from 'react-bootstrap'
import {CompileErrorCard} from './components/CompileErrorCard'
import CustomAccordionToggle from './components/CustomAccordionToggle'
interface AppState {
status: 'idle' | 'inProgress'
@ -37,11 +40,16 @@ const App = () => {
localUrl: 'http://localhost:8000/',
})
const spinnerIcon = useRef(null)
useEffect(() => {
async function start() {
try {
await remixClient.loaded()
remixClient.onFileChange((name) => setContract(name))
remixClient.onFileChange((name) => {
setOutput({})
setContract(name)
})
remixClient.onNoFileSelected(() => setContract(''))
} catch (err) {
console.log(err)
@ -68,9 +76,6 @@ const App = () => {
useEffect(() => {
remixClient.eventEmitter.on('setOutput', (payload) => {
if (payload.status === 'failed') {
console.error('Error in the compiler', payload)
}
setOutput(payload)
})
@ -98,17 +103,17 @@ const App = () => {
setOutput(remixClient.compilerOutput)
}
const startingCompilation = () => {
if (!spinnerIcon.current) return
spinnerIcon.current.setAttribute('title', 'compiling...')
spinnerIcon.current.classList.remove('remixui_bouncingIcon')
spinnerIcon.current.classList.add('remixui_spinningIcon')
}
const [toggleAccordion, setToggleAccordion] = useState(false)
return (
<main id="vyper-plugin">
<header>
<div className="title">
<img src={'assets/vyperLogo_v2.webp'} alt="Vyper logo" />
<h4 className="pl-1">yper Compiler</h4>
</div>
<a rel="noopener noreferrer" href="https://github.com/ethereum/remix-project/tree/master/apps/vyper" target="_blank">
<i className="fab fa-github"></i>
</a>
</header>
<section>
<div className="px-3 pt-3 mb-3 w-100">
<CustomTooltip placement="bottom" tooltipText="Clone Vyper examples. Switch to the File Explorer to see the examples.">
@ -117,25 +122,49 @@ const App = () => {
</Button>
</CustomTooltip>
</div>
<Accordion className="border-0 w-100 mb-3 accordion-background">
<div className="border-0">
<div className="">
<CustomAccordionToggle eventKey="0">
<span className="">Advanced Compiler Settings</span>
</CustomAccordionToggle>
</div>
<Accordion.Collapse eventKey="0">
<div className="pl-3 pt-3 border-top-0">
<Form>
<div className="d-flex flex-row gap-5 mb-3 mt-2">
<Form.Check inline data-id="remote-compiler" type="radio" value={state.environment} checked={state.environment === 'remote'} onChange={() => setEnvironment('remote')} label="Remote Compiler" style={{cursor: state.environment === 'remote' ? 'default' : 'pointer'}} className="d-flex mr-4" />
<Form.Check inline id="local-compiler" data-id="local-compiler" checked={state.environment === 'local'} type="radio" name="local" value={state.environment} onChange={() => setEnvironment('local')} label="Local Compiler" style={{cursor: state.environment === 'local' ? 'default' : 'pointer'}} />
<Form.Check inline id="remote-compiler" data-id="remote-compiler" type="radio" name="remote" value={state.environment} checked={state.environment === 'remote'} onChange={() => setEnvironment('remote')} label="Remote Compiler" className={`${state.environment === 'remote' ? 'd-flex mr-4' : 'd-flex mr-4 cursor-status'}`} />
<Form.Check inline id="local-compiler" data-id="local-compiler" checked={state.environment === 'local'} type="radio" name="local" value={state.environment} onChange={() => setEnvironment('local')} label="Local Compiler" className={`${state.environment === 'local' ? '' : `cursor-status`}`} />
</div>
</Form>
<span className="px-3 mt-1 mb-1 small text-warning">Specify the compiler version & EVM version in the .vy file</span>
</div>
</Accordion.Collapse>
</div>
</Accordion>
<LocalUrlInput url={state.localUrl} setUrl={setLocalUrl} environment={state.environment} />
<span className="px-3 mt-1 mb-1 small text-warning">
Specify the{' '}
<a className="text-warning" target="_blank" href="https://remix-ide.readthedocs.io/en/latest/vyper.html#specify-vyper-version">
compiler version
</a>{' '}
&{' '}
<a className="text-warning" href="http://docs.vyperlang.org/en/stable/compiling-a-contract.html#setting-the-target-evm-version" target="_blank" rel="noopener noreferrer">
EVM version
</a>{' '}
in the .vy file.
</span>
<div className="px-3 w-100 mb-3 mt-1" id="compile-btn">
<CompilerButton compilerUrl={compilerUrl()} contract={contract} setOutput={(name, update) => setOutput({...output, [name]: update})} resetCompilerState={resetCompilerResultState} />
</div>
<article id="result" className="px-2 mx-2 border-top mt-3">
<article id="result" className="p-4 mx-3 border-top mt-2">
{output && Object.keys(output).length > 0 && output.status !== 'failed' ? (
<>
<VyperResult output={output} plugin={remixClient} />
</>
) : output.status === 'failed' ? (
<CompileErrorCard output={output} />
<CompileErrorCard output={output} askGpt={remixClient.askGpt} />
) : null}
</article>
</section>

@ -1,12 +1,19 @@
import {CopyToClipboard} from '@remix-ui/clipboard'
import Reaact from 'react'
export function CompileErrorCard(props: any) {
return (
<div id="vyperErrorResult" className="px-2 mx-3 alert alert-danger error" title={props.output.message}>
<i className="fas fa-exclamation-circle text-danger"></i>
<div
id="vyperErrorResult"
className=" d-flex flex-column p-2 alert alert-danger error vyper-compile-error"
title={props.output?.title}
style={{
width: '94%'
}}
>
<span
data-id="error-message"
className="text-center"
className="text-left"
style={{
overflowX: 'hidden',
textOverflow: 'ellipsis',
@ -14,6 +21,16 @@ export function CompileErrorCard(props: any) {
>
{props.output.message.trim()}
</span>
{/* <div className="d-flex flex-column pt-3 align-items-end mb-2">
<div>
<span className="border border-success text-success btn-sm" onClick={() => props.askGpt(props.output.message)}>
Ask GPT
</span>
<span className="ml-3 pt-1 py-1">
<CopyToClipboard content={props.output.message} className={`p-0 m-0 far fa-copy alert alert-danger`} direction={'top'} />
</span>
</div>
</div> */}
</div>
)
}

@ -29,7 +29,7 @@ function CompilerButton({contract, setOutput, compilerUrl, resetCompilerState}:
className="btn btn-primary w-100 d-block btn-block text-break remixui_disabled mb-1 mt-3"
>
<div className="d-flex align-items-center justify-content-center fa-1x">
<span className="fas fa-sync fa-pulse mr-1" />
{/* <span className="fas fa-sync fa-pulse mr-1" /> */}
<div className="text-truncate overflow-hidden text-nowrap">
<span>Compile</span>
<span className="ml-1 text-nowrap">{contract}</span>

@ -0,0 +1,26 @@
import React, { useState } from 'react'
import { useAccordionToggle } from 'react-bootstrap/AccordionToggle'
export type CustomAccordionToggleProps = {
children: React.ReactNode
eventKey: string
callback?: any
}
export default function CustomAccordionToggle({ children, eventKey }: CustomAccordionToggleProps) {
const [toggleAccordion, setToggleAccordion] = useState(false)
const decoratedOnClick = useAccordionToggle(eventKey, () =>
setToggleAccordion(!toggleAccordion)
)
return (
<div
onClick={decoratedOnClick}
className="d-flex flex-row justify-content-between align-items-center mx-3"
>
{children}
<i className={toggleAccordion ? 'far fa-angle-down' : 'far fa-angle-right'}></i>
</div>
)
}

@ -59,7 +59,7 @@ function VyperResult({ output, plugin }: VyperResultProps) {
return (
<>
<div className="border border-top"></div>
<div className="d-flex justify-content-center px-2 w-100 flex-column border border-bottom">
<div className="d-flex justify-content-center px-2 w-100 flex-column">
<button data-id="compilation-details" className="btn btn-secondary w-100" onClick={async () => {
await plugin?.call('vyperCompilationDetails', 'showDetails', output)
}}>

@ -31,9 +31,7 @@ export interface VyperCompilationError {
export type VyperCompilationOutput = VyperCompilationResult | VyperCompilationError
/** Check if the output is an error */
export function isCompilationError(output: VyperCompilationOutput): output is VyperCompilationError {
return output.status === 'failed'
}
export const isCompilationError = (output: VyperCompilationOutput): output is VyperCompilationError => output.status === 'failed'
export function normalizeContractPath(contractPath: string): string[] {
const paths = contractPath.split('/')
@ -52,22 +50,99 @@ function parseErrorString(errorString) {
// Split the string into lines
let lines = errorString.trim().split('\n')
// Extract the line number and message
let message = lines[1].trim()
console.log(lines)
let message = errorString.trim()
let targetLine = lines[2].split(',')
let lineColumn = targetLine[targetLine.length - 1].split(' ')[2].split(':')
let tline = lines[2].trim().split(' ')[1].split(':')
console.log('tline', tline)
const errorObject = {
status: 'failed',
message: message,
column: parseInt(lineColumn[1]),
line: parseInt(lineColumn[0])
column: tline[1],
line: tline[0]
}
message = null
targetLine = null
lineColumn = null
lines = null
tline = null
return errorObject
}
const buildError = (output) => {
if (isCompilationError(output)) {
const line = output.line
if (line) {
const lineColumnPos = {
start: {line: line - 1, column: 10},
end: {line: line - 1, column: 10}
}
// remixClient.highlight(lineColumnPos as any, _contract.name, '#e0b4b4')
} else {
const regex = output?.message?.match(/line ((\d+):(\d+))+/g)
const errors = output?.message?.split(/line ((\d+):(\d+))+/g) // extract error message
if (regex) {
let errorIndex = 0
regex.map((errorLocation) => {
const location = errorLocation?.replace('line ', '').split(':')
let message = errors[errorIndex]
errorIndex = errorIndex + 4
if (message && message?.split('\n\n').length > 0) {
try {
message = message?.split('\n\n')[message.split('\n\n').length - 1]
} catch (e) {}
}
if (location?.length > 0) {
const lineColumnPos = {
start: {line: parseInt(location[0]) - 1, column: 10},
end: {line: parseInt(location[0]) - 1, column: 10}
}
// remixClient.highlight(lineColumnPos as any, _contract.name, message)
}
})
}
}
throw new Error(output.message)
}
}
const compileReturnType = (output, contract) => {
const t: any = toStandardOutput(contract, output)
const temp = _.merge(t['contracts'][contract])
const normal = normalizeContractPath(contract)[2]
const abi = temp[normal]['abi']
const evm = _.merge(temp[normal]['evm'])
const dpb = evm.deployedBytecode
const runtimeBytecode = evm.bytecode
const methodIdentifiers = evm.methodIdentifiers
const version = output?.compilers[0]?.version ?? '0.3.10'
const optimized = output?.compilers[0]?.settings?.optimize ?? true
const evmVersion = ''
const result: {
contractName: any,
abi: any,
bytecode: any,
runtimeBytecode: any,
ir: '',
methodIdentifiers: any,
version?: '',
evmVersion?: ''
optimized?: boolean
} = {
contractName: normal,
abi,
bytecode: dpb,
runtimeBytecode,
ir: '',
methodIdentifiers,
version,
evmVersion,
optimized
}
return result
}
/**
* Compile the a contract
* @param url The url of the compiler
@ -117,6 +192,7 @@ export async function compile(url: string, contract: Contract): Promise<any> {
method: 'Get'
})).data
result = parseErrorString(intermediate[0])
console.log('error payload', intermediate)
return result
}
await new Promise((resolve) => setTimeout(() => resolve({}), 3000))
@ -181,15 +257,11 @@ export async function compileContract(contract: string, compilerUrl: string, set
try {
_contract = await remixClient.getContract()
} catch (e: any) {
// if (setOutput === null || setOutput === undefined) {
const compileResult = {
const errorGettingContract = {
status: 'failed',
message: e.message
}
remixClient.eventEmitter.emit('setOutput', compileResult)
// } else {
// setOutput('', {status: 'failed', message: e.message})
// }
remixClient.eventEmitter.emit('setOutput', errorGettingContract)
return
}
remixClient.changeStatus({
@ -198,76 +270,20 @@ export async function compileContract(contract: string, compilerUrl: string, set
title: 'Compiling'
})
let output
try {
// try {
output = await compile(compilerUrl, _contract)
console.log('checking compile result', output)
remixClient.eventEmitter.emit('setOutput', output)
} catch (e: any) {
if (output.status === 'failed') {
console.log('possible error', output)
remixClient.changeStatus({
key: 'failed',
type: 'error',
title: `${e.message} debugging`
title: 'Compilation failed...'
})
// setOutput !== null || setOutput !== undefined && setOutput('', {status: 'failed', message: e.message})
remixClient.eventEmitter.emit('setOutput', {status: 'failed', message: e.message})
remixClient.eventEmitter.emit('setOutput', {status: 'failed', message: output.message, title: 'Error compiling...', line: output.line, column: output.column})
output = null
return
}
const compileReturnType = () => {
const t: any = toStandardOutput(contract, output)
const temp = _.merge(t['contracts'][contract])
const normal = normalizeContractPath(contract)[2]
const abi = temp[normal]['abi']
const evm = _.merge(temp[normal]['evm'])
const dpb = evm.deployedBytecode
const runtimeBytecode = evm.bytecode
const methodIdentifiers = evm.methodIdentifiers
const result = {
contractName: normal,
abi: abi,
bytecode: dpb,
runtimeBytecode: runtimeBytecode,
ir: '',
methodIdentifiers: methodIdentifiers
}
return result
}
// ERROR
if (isCompilationError(output)) {
const line = output.line
if (line) {
const lineColumnPos = {
start: {line: line - 1, column: 10},
end: {line: line - 1, column: 10}
}
// remixClient.highlight(lineColumnPos as any, _contract.name, '#e0b4b4')
} else {
const regex = output?.message?.match(/line ((\d+):(\d+))+/g)
const errors = output?.message?.split(/line ((\d+):(\d+))+/g) // extract error message
if (regex) {
let errorIndex = 0
regex.map((errorLocation) => {
const location = errorLocation?.replace('line ', '').split(':')
let message = errors[errorIndex]
errorIndex = errorIndex + 4
if (message && message?.split('\n\n').length > 0) {
try {
message = message?.split('\n\n')[message.split('\n\n').length - 1]
} catch (e) {}
}
if (location?.length > 0) {
const lineColumnPos = {
start: {line: parseInt(location[0]) - 1, column: 10},
end: {line: parseInt(location[0]) - 1, column: 10}
}
// remixClient.highlight(lineColumnPos as any, _contract.name, message)
}
})
}
}
throw new Error(output.message)
}
// SUCCESS
// remixClient.discardHighlight()
remixClient.changeStatus({
@ -278,12 +294,12 @@ export async function compileContract(contract: string, compilerUrl: string, set
const data = toStandardOutput(_contract.name, output)
remixClient.compilationFinish(_contract.name, _contract.content, data)
if (setOutput === null || setOutput === undefined) {
const contractName = _contract['name']
const compileResult = compileReturnType()
const compileResult = compileReturnType(output, contractName)
if (setOutput === null || setOutput === undefined) {
remixClient.eventEmitter.emit('setOutput', { contractName, compileResult })
} else {
setOutput(_contract.name, compileReturnType())
remixClient.eventEmitter.emit('setOutput', { contractName, compileResult })
}
} catch (err: any) {
remixClient.changeStatus({

@ -42,7 +42,7 @@ export class RemixClient extends PluginClient {
this.eventEmitter.emit('resetCompilerState', {})
}
async vyperCompileCustomAction(action: customAction) {
async vyperCompileCustomAction(action?: customAction) {
//read selected contract from file explorer and create contract type
const contract = await this.getContract()
//compile contract
@ -60,6 +60,15 @@ export class RemixClient extends PluginClient {
}
}
async askGpt(message: string) {
try {
await this.client.call('openaigpt', 'message', message)
} catch (err) {
console.error('unable to askGpt')
console.error(err)
}
}
async cloneVyperRepo() {
try {
// @ts-ignore
@ -114,7 +123,7 @@ export class RemixClient extends PluginClient {
await this.client.call('editor', 'addAnnotation', annotation, name)
}
/** Remove current Hightlight */
/** Remove current Highlight */
async discardHighlight() {
await this.client.call('editor', 'discardHighlight')
await this.client.call('editor', 'clearAnnotations')

@ -7,8 +7,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="stylesheet" integrity="ha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
</head>
<body>
<div id="root"></div>
<script src="https://kit.fontawesome.com/41dd021e94.js" crossorigin="anonymous"></script>
</body>
</html>

@ -1,12 +1,12 @@
{
"name": "vyper",
"displayName": "Vyper",
"displayName": "Vyper Compiler",
"methods": ["getCompilationResult", "compile", "vyperCompileCustomAction"],
"url": "https://ipfs-cluster.ethdevops.io/ipfs/QmbmPzUg7ghTKcF2eo64zm1k1LKdibYfqYmiqXkHKXks8r",
"documentation": "https://remix-ide.readthedocs.io/en/latest/plugin_list.html",
"description": "Compile vyper contracts",
"kind": "compiler",
"icon": "data:image/svg+xml;base64,PHN2ZyBpZD0iRmxhdF9Mb2dvIiBkYXRhLW5hbWU9IkZsYXQgTG9nbyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMjA0OCAxNzczLjYyIj4gIDx0aXRsZT52eXBlci1sb2dvLWZsYXQ8L3RpdGxlPiAgPHBvbHlsaW5lIHBvaW50cz0iMTAyNCA4ODYuODEgNzY4IDEzMzAuMjIgMTAyNCAxNzczLjYyIDEyODAgMTMzMC4yMiAxMDI0IDg4Ni44MSIgc3R5bGU9ImZpbGw6IzMzMyIvPiAgPHBvbHlsaW5lIHBvaW50cz0iMTI4MCA0NDMuNDEgMTAyNCA4ODYuODEgMTI4MCAxMzMwLjIyIDE1MzYgODg2LjgxIDEyODAgNDQzLjQxIiBzdHlsZT0iZmlsbDojNjY2Ii8+ICA8cG9seWxpbmUgcG9pbnRzPSI3NjggNDQzLjQxIDUxMiA4ODYuODEgNzY4IDEzMzAuMjIgMTAyNCA4ODYuODEgNzY4IDQ0My40MSIgc3R5bGU9ImZpbGw6IzY2NiIvPiAgPHBvbHlsaW5lIHBvaW50cz0iMTUzNiAwIDEyODAgNDQzLjQxIDE1MzYgODg2LjgxIDE3OTIgNDQzLjQxIDE1MzYgMCIgc3R5bGU9ImZpbGw6IzhjOGM4YyIvPiAgPHBvbHlsaW5lIHBvaW50cz0iMTE1MiAyMjEuNyA4OTYgMjIxLjcgNzY4IDQ0My40MSAxMDI0IDg4Ni44MSAxMjgwIDQ0My40MSAxMTUyIDIyMS43IiBzdHlsZT0iZmlsbDojOGM4YzhjIi8+ICA8cG9seWxpbmUgcG9pbnRzPSI1MTIgMCAyNTYgNDQzLjQxIDUxMiA4ODYuODEgNzY4IDQ0My40MSA1MTIgMCIgc3R5bGU9ImZpbGw6IzhjOGM4YyIvPiAgPHBvbHlsaW5lIHBvaW50cz0iMjA0OCAwIDE1MzYgMCAxNzkyIDQ0My40IDIwNDggMCIgc3R5bGU9ImZpbGw6I2IyYjJiMiIvPiAgPHBvbHlsaW5lIHBvaW50cz0iNTEyIDAgMCAwIDI1NiA0NDMuNCA1MTIgMCIgc3R5bGU9ImZpbGw6I2IyYjJiMiIvPjwvc3ZnPg==",
"icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzM4IiBoZWlnaHQ9IjM3NiIgdmlld0JveD0iMCAwIDMzOCAzNzYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0xOTUuMzA0IDMxMS44MzdMODIuNTE4IDE5OS4wODRDNzcuOTI0MSAxOTQuMzA0IDc1LjM5MjcgMTg3LjgzNyA3NS4zOTI3IDE4MC42MlYxOS42OTE0Qzc1LjM5MjcgMTAuMzE4OCA2Ni4wMTc0IDAuOTQ2MTI3IDU2LjY0MiAwLjk0NjEyN0gxOS4wNDY3QzkuNjcxMjggMC45NDYxMjcgMC4yOTU4OTggMTAuMzE4OCAwLjI5NTg5OCAxOS42OTE0VjIwNy4xNDVDMC4yOTU4OTggMjE3LjA4IDMuOTUyMyAyMjYuNjQgMTAuOTgzOCAyMzMuNjY5TDE0Mi4yMzkgMzY0Ljg4NkMxNDkuNTUyIDM3Mi4xOTcgMTU5LjExNSAzNzUuODUyIDE2OC43NzIgMzc1Ljg1MkgxODcuNTIyQzE5Ny45MjkgMzc1Ljg1MiAyMDYuMjczIDM2Ny40MTcgMjA2LjI3MyAzNTcuMTA3VjMzOC40NTZDMjA2LjI3MyAzMjguODAyIDIwMi42MTcgMzE5LjI0MiAxOTUuMzA0IDMxMS45MzFWMzExLjgzN1oiIGZpbGw9IiMxODBDMjUiLz4KPHBhdGggZD0iTTMzNy44MSAxOS41OTc3QzMzNy44MSAxMC4xMzEzIDMyOC41MjkgMC44NTI0MTcgMzE5LjA1OSAwLjg1MjQxN0gyODEuNDY0QzI3Mi4wODkgMC44NTI0MTcgMjYyLjcxMyAxMC4yMjUxIDI2Mi43MTMgMTkuNTk3N1YxODAuNDMzQzI2Mi43MTMgMTg3LjY1IDI1OS45MDEgMTk0LjExNyAyNTUuMjEzIDE5OC45OUwyMTcuNDMgMjM2Ljc2MkMyMTAuMTE4IDI0NC4wNzMgMjA2LjQ2MSAyNTMuNjMzIDIwNi40NjEgMjYzLjI4N1YyODIuMDMyQzIwNi40NjEgMjkyLjQzNiAyMTQuODk5IDMwMC43NzggMjI1LjIxMiAzMDAuNzc4SDI0My45NjNDMjUzLjUyNiAzMDAuNzc4IDI2My4xODIgMjk3LjEyMiAyNzAuNDk1IDI4OS44MTFMMzI2Ljc0NyAyMzMuNTc2QzMzMy43NzkgMjI2LjU0NiAzMzcuNzE2IDIxNi45ODYgMzM3LjcxNiAyMDcuMDUxVjE5LjU5NzdIMzM3LjgxWiIgZmlsbD0iIzE4MEMyNSIvPgo8L3N2Zz4K",
"location": "sidePanel",
"repo": "https://github.com/ethereum/remix-project/tree/master/apps/vyper",
"maintainedBy": "Remix",

@ -1,6 +1,6 @@
{
"name": "@remix-project/ghaction-helper",
"version": "0.1.22",
"version": "0.1.23",
"description": "Solidity Tests GitHub Action Helper",
"main": "src/index.js",
"scripts": {
@ -19,17 +19,17 @@
},
"homepage": "https://github.com/ethereum/remix-project#readme",
"devDependencies": {
"@remix-project/remix-solidity": "^0.5.28",
"@remix-project/remix-solidity": "^0.5.29",
"@types/chai": "^4.3.4",
"typescript": "^4.9.3"
},
"dependencies": {
"@ethereum-waffle/chai": "^3.4.4",
"@remix-project/remix-simulator": "^0.2.42",
"@remix-project/remix-simulator": "^0.2.43",
"chai": "^4.3.7",
"ethers": "^5.7.2",
"web3": "^4.1.1"
},
"types": "./src/index.d.ts",
"gitHead": "817089ab1f206f5e195756a4051afb812ec26901"
"gitHead": "d08019670b3095207b262dac71c55d8467a81f85"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-analyzer",
"version": "0.5.51",
"version": "0.5.52",
"description": "Tool to perform static analysis on Solidity smart contracts",
"scripts": {
"test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts"
@ -25,8 +25,8 @@
"@ethereumjs/tx": "^4.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethereumjs/vm": "^6.4.1",
"@remix-project/remix-astwalker": "^0.0.72",
"@remix-project/remix-lib": "^0.5.49",
"@remix-project/remix-astwalker": "^0.0.73",
"@remix-project/remix-lib": "^0.5.50",
"async": "^2.6.2",
"ethers": "^5.4.2",
"ethjs-util": "^0.1.6",
@ -50,6 +50,6 @@
"typescript": "^3.7.5"
},
"typings": "src/index.d.ts",
"gitHead": "817089ab1f206f5e195756a4051afb812ec26901",
"gitHead": "d08019670b3095207b262dac71c55d8467a81f85",
"main": "./src/index.js"
}

@ -22,7 +22,7 @@ export default class abstractAstView {
file2: import "file1" as x; contract c{}
therefore we have two contracts with the same name c. At the moment this is not handled because alias name "x" is not
available in the current AST implementation thus can not be resolved.
Additionally the fullQuallified function names e.g. [contractName].[functionName](param1Type, param2Type, ... ) must be prefixed to
Additionally the fullQualified function names e.g. [contractName].[functionName](param1Type, param2Type, ... ) must be prefixed to
fully support this and when inheritance is resolved it must include alias resolving e.g x.c = file1.c
*/
multipleContractsWithSameName = false
@ -36,14 +36,14 @@ export default class abstractAstView {
* "functions": [
* {
* "node": {}, // actual AST Node of the function
* "relevantNodes": [], // AST nodes in the function that are relevant for the anlysis of this function
* "relevantNodes": [], // AST nodes in the function that are relevant for the analysis of this function
* "modifierInvocations": [], // Modifier invocation AST nodes that are applied on this function
* "localVariables": [], // Local variable declaration nodes
* "parameters": [] // Parameter types of the function in order of definition
* "returns": [] // list of return vars as { type: ... , name: ... }
* }
* ],
* "modifiers": [], // Modifiers definded by the contract, format similar to functions
* "modifiers": [], // Modifiers defined by the contract, format similar to functions
* "inheritsFrom": [], // Names of contract this one inherits from in order of definition
* "stateVariables": [] // AST nodes of all State variables
* }
@ -130,7 +130,7 @@ export default class abstractAstView {
if (inheritsFrom) {
currentContract.stateVariables = currentContract.stateVariables.concat(inheritsFrom.stateVariables)
} else {
console.log('abstractAstView.js: could not find contract defintion inherited from ' + inheritsFromName)
console.log('abstractAstView.js: could not find contract definition inherited from ' + inheritsFromName)
}
})
}
@ -138,7 +138,7 @@ export default class abstractAstView {
private setCurrentContract (contract: ContractHLAst): void {
const name: string = getContractName(contract.node)
if (this.contracts.map((c: ContractHLAst) => getContractName(c.node)).filter((n) => n === name).length > 0) {
console.log('abstractAstView.js: two or more contracts with the same name dectected, import aliases not supported at the moment')
console.log('abstractAstView.js: two or more contracts with the same name detected, import aliases not supported at the moment')
this.multipleContractsWithSameName = true
}
this.currentContractIndex = (this.contracts.push(contract) - 1)

@ -1,6 +1,6 @@
import category from './categories'
import {
isInteraction, isEffect, isLocalCallGraphRelevantNode, getFullQuallyfiedFuncDefinitionIdent,
isInteraction, isEffect, isLocalCallGraphRelevantNode, getFullQualifiedFuncDefinitionIdent,
isWriteOnStateVariable, isStorageVariableDeclaration, getFullQualifiedFunctionCallIdent, getCompilerVersion
} from './staticAnalysisCommon'
import algorithm from './algorithmCategories'
@ -36,7 +36,7 @@ export default class checksEffectsInteraction implements AnalyzerModule {
contracts.forEach((contract) => {
contract.functions.forEach((func) => {
func['changesState'] = this.checkIfChangesState(
getFullQuallyfiedFuncDefinitionIdent(
getFullQualifiedFuncDefinitionIdent(
contract.node,
func.node,
func.parameters
@ -49,7 +49,7 @@ export default class checksEffectsInteraction implements AnalyzerModule {
})
contract.functions.forEach((func: FunctionHLAst) => {
if (this.isPotentialVulnerableFunction(func, this.getContext(callGraph, contract, func))) {
const funcName: string = getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
const funcName: string = getFullQualifiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
let comments: string = (hasModifiers) ? 'Note: Modifiers are currently not considered by this static analysis.' : ''
comments += (multipleContractsWithSameName) ? 'Note: Import aliases are currently not supported by this static analysis.' : ''
warnings.push({

@ -1,7 +1,7 @@
import category from './categories'
import {
isLowLevelCall, isTransfer, isExternalDirectCall, isEffect, isLocalCallGraphRelevantNode, isSelfdestructCall,
isDeleteUnaryOperation, isPayableFunction, isConstructor, getFullQuallyfiedFuncDefinitionIdent, hasFunctionBody,
isDeleteUnaryOperation, isPayableFunction, isConstructor, getFullQualifiedFuncDefinitionIdent, hasFunctionBody,
isConstantFunction, isWriteOnStateVariable, isStorageVariableDeclaration, isCallToNonConstLocalFunction,
getFullQualifiedFunctionCallIdent
} from './staticAnalysisCommon'
@ -50,7 +50,7 @@ export default class constantFunctions implements AnalyzerModule {
func['potentiallyshouldBeConst'] = false
} else {
func['potentiallyshouldBeConst'] = this.checkIfShouldBeConstant(
getFullQuallyfiedFuncDefinitionIdent(
getFullQualifiedFuncDefinitionIdent(
contract.node,
func.node,
func.parameters
@ -65,7 +65,7 @@ export default class constantFunctions implements AnalyzerModule {
})
contract.functions.filter((func: FunctionHLAst) => hasFunctionBody(func.node)).forEach((func: FunctionHLAst) => {
if (isConstantFunction(func.node) !== func['potentiallyshouldBeConst']) {
const funcName: string = getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
const funcName: string = getFullQualifiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
let comments: string = (hasModifiers) ? 'Note: Modifiers are currently not considered by this static analysis.' : ''
comments += (multipleContractsWithSameName) ? 'Note: Import aliases are currently not supported by this static analysis.' : ''
if (func['potentiallyshouldBeConst']) {

@ -3,7 +3,7 @@
import { FunctionHLAst, ContractHLAst, FunctionCallGraph, ContractCallGraph, Context, FunctionCallAstNode } from '../../types'
import {
isLocalCallGraphRelevantNode, isExternalDirectCall, getFullQualifiedFunctionCallIdent,
getFullQuallyfiedFuncDefinitionIdent, getContractName
getFullQualifiedFuncDefinitionIdent as getFullQualifiedFuncDefinitionIdent, getContractName
} from './staticAnalysisCommon'
type filterNodesFunction = (node: FunctionCallAstNode) => boolean
@ -39,7 +39,7 @@ function buildLocalFuncCallGraphInternal (functions: FunctionHLAst[], nodeFilter
* }
* },
* "foo": {
* "contract": {...}, // Contract node as definded in abstractAstView.js
* "contract": {...}, // Contract node as defined in abstractAstView.js
* "functions": {} // map from full qualified function name to func node
* }
* }
@ -52,7 +52,7 @@ export function buildGlobalFuncCallGraph (contracts: ContractHLAst[]): Record<st
contracts.forEach((contract: ContractHLAst) => {
const filterNodes: filterNodesFunction = (node: FunctionCallAstNode) => { return isLocalCallGraphRelevantNode(node) || isExternalDirectCall(node) }
const getNodeIdent: NodeIdentFunction = (node: FunctionCallAstNode) => { return getFullQualifiedFunctionCallIdent(contract.node, node) }
const getFunDefIdent: FunDefIdentFunction = (funcDef: FunctionHLAst) => { return getFullQuallyfiedFuncDefinitionIdent(contract.node, funcDef.node, funcDef.parameters) }
const getFunDefIdent: FunDefIdentFunction = (funcDef: FunctionHLAst) => { return getFullQualifiedFuncDefinitionIdent(contract.node, funcDef.node, funcDef.parameters) }
callGraph[getContractName(contract.node)] = { contract: contract, functions: buildLocalFuncCallGraphInternal(contract.functions, filterNodes, getNodeIdent, getFunDefIdent) }
})

@ -1,5 +1,5 @@
import category from './categories'
import { hasFunctionBody, getFullQuallyfiedFuncDefinitionIdent, getEffectedVariableName } from './staticAnalysisCommon'
import { hasFunctionBody, getFullQualifiedFuncDefinitionIdent, getEffectedVariableName } from './staticAnalysisCommon'
import algorithm from './algorithmCategories'
import AbstractAst from './abstractAstView'
import {
@ -28,7 +28,7 @@ export default class noReturn implements AnalyzerModule {
contracts.forEach((contract: ContractHLAst) => {
contract.functions.filter((func: FunctionHLAst) => hasFunctionBody(func.node)).forEach((func: FunctionHLAst) => {
const funcName: string = getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
const funcName: string = getFullQualifiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
if (this.hasNamedAndUnnamedReturns(func)) {
warnings.push({
warning: `${funcName}: Mixing of named and unnamed return parameters is not advised.`,

@ -1,5 +1,5 @@
import category from './categories'
import { getDeclaredVariableName, getFullQuallyfiedFuncDefinitionIdent } from './staticAnalysisCommon'
import { getDeclaredVariableName, getFullQualifiedFuncDefinitionIdent } from './staticAnalysisCommon'
import algorithm from './algorithmCategories'
import AbstractAst from './abstractAstView'
import { get } from 'fast-levenshtein'
@ -35,7 +35,7 @@ export default class similarVariableNames implements AnalyzerModule {
contracts.forEach((contract) => {
contract.functions.forEach((func) => {
const funcName: string = getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
const funcName: string = getFullQualifiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
let hasModifiersComments = ''
if (hasModifiers) {
hasModifiersComments = 'Note: Modifiers are currently not considered by this static analysis.'

@ -181,7 +181,7 @@ function getFunctionCallType (func: FunctionCallAstNode): string {
/**
* Get the variable name written to by a effect node, except for inline assembly because there is no information to find out where we write to. Trows if not a effect node or is inlineassmbly.
* Example: x = 10; => x
* @effectNode {ASTNode} Assignmnet node
* @effectNode {ASTNode} Assignment node
* @return {string} variable name written to
*/
function getEffectedVariableName (effectNode: AssignmentAstNode | UnaryOperationAstNode): string {
@ -439,8 +439,8 @@ function getFullQualifiedFunctionCallIdent (contract: ContractDefinitionAstNode,
else throw new Error('staticAnalysisCommon.js: Can not get function name from non function call node')
}
function getFullQuallyfiedFuncDefinitionIdent (contract: ContractDefinitionAstNode, func: FunctionDefinitionAstNode, paramTypes: any[]): string {
return getContractName(contract) + '.' + getFunctionDefinitionName(func) + '(' + util.concatWithSeperator(paramTypes, ',') + ')'
function getFullQualifiedFuncDefinitionIdent (contract: ContractDefinitionAstNode, func: FunctionDefinitionAstNode, paramTypes: any[]): string {
return getContractName(contract) + '.' + getFunctionDefinitionName(func) + '(' + util.concatWithSeparator(paramTypes, ',') + ')'
}
function getUnAssignedTopLevelBinOps (subScope: BlockAstNode | IfStatementAstNode | WhileStatementAstNode | ForStatementAstNode): ExpressionStatementAstNode[] {
@ -630,7 +630,7 @@ function isStateVariable (name: string, stateVariables: VariableDeclarationAstNo
}
/**
* True if is function definition that is flaged as constant
* True if is function definition that is flagged as constant
* @node {ASTNode} some AstNode
* @return {bool}
*/
@ -639,7 +639,7 @@ function isConstantFunction (node: FunctionDefinitionAstNode): boolean {
}
/**
* True if variable decalaration is converted into a getter method
* True if variable declaration is converted into a getter method
* @node {ASTNode} variable declaration AstNode
* @return {bool}
*/
@ -1059,11 +1059,11 @@ function findFirstSubNodeLTR (node: any, type: string): any {
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function buildFunctionSignature (paramTypes: any[], returnTypes: any[], isPayable: boolean, additionalMods?: any): string {
return 'function (' + util.concatWithSeperator(paramTypes, ',') + ')' + ((isPayable) ? ' payable' : '') + ((additionalMods) ? ' ' + additionalMods : '') + ((returnTypes.length) ? ' returns (' + util.concatWithSeperator(returnTypes, ',') + ')' : '')
return 'function (' + util.concatWithSeparator(paramTypes, ',') + ')' + ((isPayable) ? ' payable' : '') + ((additionalMods) ? ' ' + additionalMods : '') + ((returnTypes.length) ? ' returns (' + util.concatWithSeparator(returnTypes, ',') + ')' : '')
}
function buildAbiSignature (funName: string, paramTypes: any[]): string {
return funName + '(' + util.concatWithSeperator(paramTypes, ',') + ')'
return funName + '(' + util.concatWithSeparator(paramTypes, ',') + ')'
}
// To create the method signature similar to contract.evm.gasEstimates.external object
@ -1157,7 +1157,7 @@ export {
getLibraryCallContractName,
getLibraryCallMemberName,
getFullQualifiedFunctionCallIdent,
getFullQuallyfiedFuncDefinitionIdent,
getFullQualifiedFuncDefinitionIdent as getFullQualifiedFuncDefinitionIdent,
getStateVariableDeclarationsFromContractNode,
getFunctionOrModifierDefinitionParameterPart,
getFunctionDefinitionReturnParameterPart,

@ -25,7 +25,7 @@ export default class stringBytesLength implements AnalyzerModule {
const version = getCompilerVersion(compilationResults.contracts)
if (this.stringToBytesConversions.length > 0 && this.bytesLengthChecks.length > 0) {
return [{
warning: '"bytes" and "string" lengths are not the same since strings are assumed to be UTF-8 encoded (according to the ABI defintion) therefore one character is not nessesarily encoded in one byte of data.',
warning: '"bytes" and "string" lengths are not the same since strings are assumed to be UTF-8 encoded (according to the ABI definition) therefore one character is not necessarily encoded in one byte of data.',
location: this.bytesLengthChecks[0].src,
more: `https://solidity.readthedocs.io/en/${version}/abi-spec.html#argument-encoding`
}]

@ -122,7 +122,7 @@ export interface ContractCallGraph {
}
/// //////////////////////////////////////////////////////////
/// ////////// Specfic AST Nodes /////////////////////////////
/// ////////// Specific AST Nodes ////////////////////////////
/// //////////////////////////////////////////////////////////
interface TypeDescription {

@ -286,11 +286,11 @@ test('staticAnalysisCommon.getFullQualifiedFunctionCallIdent', function (t) {
t.throws(() => common.getFullQualifiedFunctionCallIdent(contractDefinition, assignment), new RegExp('staticAnalysisCommon.js: Can not get function name from non function call node'), 'throws on wrong type')
})
test('staticAnalysisCommon.getFullQuallyfiedFuncDefinitionIdent', function (t) {
test('staticAnalysisCommon.getFullQualifiedFuncDefinitionIdent', function (t) {
t.plan(3)
t.ok(common.getFullQuallyfiedFuncDefinitionIdent(contractDefinition, functionDefinition, ['uint256', 'bool']) === 'C.f(uint256,bool)', 'creates right signature')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent(contractDefinition, parameterFunctionCall, ['uint256', 'bool']), new RegExp('staticAnalysisCommon.js: not a FunctionDefinition Node'), 'throws on wrong nodes')
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent(parameterFunctionCall, functionDefinition, ['uint256', 'bool']), new RegExp('staticAnalysisCommon.js: not a ContractDefinition Node'), 'throws on wrong nodes')
t.ok(common.getFullQualifiedFuncDefinitionIdent(contractDefinition, functionDefinition, ['uint256', 'bool']) === 'C.f(uint256,bool)', 'creates right signature')
t.throws(() => common.getFullQualifiedFuncDefinitionIdent(contractDefinition, parameterFunctionCall, ['uint256', 'bool']), new RegExp('staticAnalysisCommon.js: not a FunctionDefinition Node'), 'throws on wrong nodes')
t.throws(() => common.getFullQualifiedFuncDefinitionIdent(parameterFunctionCall, functionDefinition, ['uint256', 'bool']), new RegExp('staticAnalysisCommon.js: not a ContractDefinition Node'), 'throws on wrong nodes')
})
test('staticAnalysisCommon.getSplittedTypeDesc', function (t) {

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-astwalker",
"version": "0.0.72",
"version": "0.0.73",
"description": "Tool to walk through Solidity AST",
"main": "src/index.js",
"scripts": {
@ -37,7 +37,7 @@
"@ethereumjs/tx": "^4.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethereumjs/vm": "^6.4.1",
"@remix-project/remix-lib": "^0.5.49",
"@remix-project/remix-lib": "^0.5.50",
"@types/tape": "^4.2.33",
"async": "^2.6.2",
"ethers": "^5.4.2",
@ -53,6 +53,6 @@
"tap-spec": "^5.0.0"
},
"typings": "src/index.d.ts",
"gitHead": "817089ab1f206f5e195756a4051afb812ec26901",
"gitHead": "d08019670b3095207b262dac71c55d8467a81f85",
"types": "./src/index.d.ts"
}

@ -8,3 +8,4 @@ export * from './types/contract'
export { LinkLibraries, DeployLibraries } from './lib/link-libraries'
export { OpenZeppelinProxy } from './lib/openzeppelin-proxy'
export { fetchContractFromEtherscan } from './lib/helpers/fetch-etherscan'
export { fetchContractFromBlockscout } from './lib/helpers/fetch-blockscout'

@ -142,7 +142,7 @@ export class CompilerImports extends Plugin {
/**
* import the content of @arg url.
* first look in the browser localstorage (browser explorer) or locahost explorer. if the url start with `browser/*` or `localhost/*`
* first look in the browser localstorage (browser explorer) or localhost explorer. if the url start with `browser/*` or `localhost/*`
* then check if the @arg url is located in the localhost, in the node_modules or installed_contracts folder
* then check if the @arg url match any external url
*
@ -185,14 +185,14 @@ export class CompilerImports extends Plugin {
} else {
const localhostProvider = await this.call('fileManager', 'getProviderByName', 'localhost')
if (localhostProvider.isConnected()) {
const splitted = /([^/]+)\/(.*)$/g.exec(url)
const split = /([^/]+)\/(.*)$/g.exec(url)
const possiblePaths = ['localhost/installed_contracts/' + url]
// pick remix-tests library contracts from '.deps'
if (url.startsWith('remix_')) possiblePaths.push('localhost/.deps/remix-tests/' + url)
if (splitted) possiblePaths.push('localhost/installed_contracts/' + splitted[1] + '/contracts/' + splitted[2])
if (split) possiblePaths.push('localhost/installed_contracts/' + split[1] + '/contracts/' + split[2])
possiblePaths.push('localhost/node_modules/' + url)
if (splitted) possiblePaths.push('localhost/node_modules/' + splitted[1] + '/contracts/' + splitted[2])
if (split) possiblePaths.push('localhost/node_modules/' + split[1] + '/contracts/' + split[2])
for (const path of possiblePaths) {
try {

@ -30,12 +30,12 @@ export class FetchAndCompile extends Plugin {
}
/**
* Fetch compiliation metadata from source-Verify from a given @arg contractAddress - https://github.com/ethereum/source-verify
* Fetch compilation metadata from source-Verify from a given @arg contractAddress - https://github.com/ethereum/source-verify
* Put the artifacts in the file explorer
* Compile the code using Solidity compiler
* Returns compilation data
*
* @param {string} contractAddress - Address of the contrac to resolve
* @param {string} contractAddress - Address of the contract to resolve
* @param {string} deployedBytecode - deployedBytecode of the contract
* @param {string} targetPath - Folder where to save the compilation arfefacts
* @return {CompilerAbstract} - compilation data targeting the given @arg contractAddress
@ -72,7 +72,7 @@ export class FetchAndCompile extends Plugin {
compilationTargets,
settings,
async (url, cb) => {
// we first try to resolve the content from the compilation target using a more appropiate path
// we first try to resolve the content from the compilation target using a more appropriate path
const path = `${targetPath}/${url}`
if (compilationTargets[path] && compilationTargets[path].content) {
return cb(null, compilationTargets[path].content)
@ -100,7 +100,7 @@ export class FetchAndCompile extends Plugin {
compilationTargets,
settings,
async (url, cb) => {
// we first try to resolve the content from the compilation target using a more appropiate path
// we first try to resolve the content from the compilation target using a more appropriate path
const path = `${targetPath}/${url}`
if (compilationTargets[path] && compilationTargets[path].content) {
return cb(null, compilationTargets[path].content)
@ -183,7 +183,7 @@ export class FetchAndCompile extends Plugin {
compilationTargets,
settings,
async (url, cb) => {
// we first try to resolve the content from the compilation target using a more appropiate path
// we first try to resolve the content from the compilation target using a more appropriate path
const path = `${targetPath}/${url}`
if (compilationTargets[path] && compilationTargets[path].content) {
return cb(null, compilationTargets[path].content)

@ -118,7 +118,10 @@ export class GistHandler extends Plugin {
const workspaces = await this.call('filePanel', 'getWorkspaces')
const found = workspaces.find((workspace) => workspace.name === gistIdWorkspace)
if (found) {
await this.call('notification', 'alert', `workspace "${gistIdWorkspace}" already exist`)
await this.call('notification', 'alert', {
id: 'gistAlert',
message: `workspace "${gistIdWorkspace}" already exists`,
})
return
}
await this.call('filePanel', 'createWorkspace', 'gist ' + gistId, '', true)

@ -0,0 +1,67 @@
export const fetchContractFromBlockscout = async (plugin, endpoint, contractAddress, targetPath, shouldSetFile = true) => {
let data
const compilationTargets = {}
try {
data = await fetch('https://' + endpoint + '/api?module=contract&action=getsourcecode&address=' + contractAddress)
data = await data.json()
console.log(data)
// blockscout api doc https://blockscout.com/poa/core/api-docs
if (data.message === 'OK' && data.status === "1") {
if (data.result.length) {
if (!data.result[0].SourceCode || data.result[0].SourceCode === '') {
throw new Error(`contract not verified on Blockscout ${endpoint} network`)
}
}
} else throw new Error('unable to retrieve contract data ' + data.message)
} catch (e) {
throw new Error('unable to retrieve contract data: ' + e.message)
}
if (!data || !data.result) {
return null
}
if (data.result[0].FileName === '') {
const fileName = `${targetPath}/${data.result[0].ContractName}.sol`
if (shouldSetFile) await plugin.call('fileManager', 'setFile', fileName, data.result[0].SourceCode)
compilationTargets[fileName] = { content: data.result[0].SourceCode }
} else {
const sources = {}
sources[data.result[0].FileName] = data.result[0].SourceCode
if (data.result[0].AdditionalSources && Array.isArray(data.result[0].AdditionalSources)) {
for (const object of data.result[0].AdditionalSources) {
sources[object.Filename] = object.SourceCode
}
}
for (let [file, source] of Object.entries(sources)) { // eslint-disable-line
file = file.replace('browser/', '') // should be fixed in the remix IDE end.
file = file.replace(/^\//g, '') // remove first slash.
if (await plugin.call('contentImport', 'isExternalUrl', file)) {
// nothing to do, the compiler callback will handle those
} else {
const path = `${targetPath}/${file}`
const content = source
if (shouldSetFile) await plugin.call('fileManager', 'setFile', path, content)
compilationTargets[path] = { content }
}
}
}
let runs = 0
try {
runs = parseInt(data.result[0].OptimizationRuns)
} catch (e) { }
const settings = {
version: data.result[0].CompilerVersion.replace(/^v/, ''),
language: 'Solidity',
evmVersion: data.result[0].EVMVersion.toLowerCase(),
optimize: data.result[0].OptimizationUsed === 'true',
runs
}
return {
settings,
compilationTargets
}
}

@ -13,11 +13,11 @@ const profile = {
export class OffsetToLineColumnConverter extends Plugin {
lineBreakPositionsByContent: Record<number, Array<number>>
sourceMappingDecoder: any
offsetConvertion: any
offsetConversion: any
constructor () {
super(profile)
this.lineBreakPositionsByContent = {}
this.offsetConvertion = {}
this.offsetConversion = {}
this.sourceMappingDecoder = sourceMappingDecoder
}
@ -49,12 +49,12 @@ export class OffsetToLineColumnConverter extends Plugin {
}
const token = `${rawLocation.start}:${rawLocation.length}:${file}`
if (this.offsetConvertion[token]) {
return this.offsetConvertion[token]
if (this.offsetConversion[token]) {
return this.offsetConversion[token]
} else {
const convertion = this.sourceMappingDecoder.convertOffsetToLineColumn(rawLocation, this.lineBreakPositionsByContent[file])
this.offsetConvertion[token] = convertion
return convertion
const conversion = this.sourceMappingDecoder.convertOffsetToLineColumn(rawLocation, this.lineBreakPositionsByContent[file])
this.offsetConversion[token] = conversion
return conversion
}
}
@ -74,7 +74,7 @@ export class OffsetToLineColumnConverter extends Plugin {
*/
clear () {
this.lineBreakPositionsByContent = {}
this.offsetConvertion = {}
this.offsetConversion = {}
}
/**

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-debug",
"version": "0.5.42",
"version": "0.5.43",
"description": "Tool to debug Ethereum transactions",
"contributors": [
{
@ -26,10 +26,10 @@
"@ethereumjs/tx": "^4.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethereumjs/vm": "^6.4.1",
"@remix-project/remix-astwalker": "^0.0.72",
"@remix-project/remix-lib": "^0.5.49",
"@remix-project/remix-simulator": "^0.2.42",
"@remix-project/remix-solidity": "^0.5.28",
"@remix-project/remix-astwalker": "^0.0.73",
"@remix-project/remix-lib": "^0.5.50",
"@remix-project/remix-simulator": "^0.2.43",
"@remix-project/remix-solidity": "^0.5.29",
"ansi-gray": "^0.1.1",
"async": "^2.6.2",
"color-support": "^1.1.3",
@ -69,6 +69,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme",
"typings": "src/index.d.ts",
"gitHead": "817089ab1f206f5e195756a4051afb812ec26901",
"gitHead": "d08019670b3095207b262dac71c55d8467a81f85",
"types": "./src/index.d.ts"
}

@ -10,8 +10,8 @@ export class CodeResolver {
constructor ({ getCode, fork }) {
this.getCode = getCode
this.bytecodeByAddress = {} // bytes code by contract addesses
this.instructionsByAddress = {} // assembly items instructions list by contract addesses
this.bytecodeByAddress = {} // bytes code by contract addresses
this.instructionsByAddress = {} // assembly items instructions list by contract addresses
this.instructionsIndexByBytesOffset = {} // mapping between bytes offset and instructions index.
this.fork = fork
}

@ -229,7 +229,7 @@ function getEnum (type, stateDefinitions, contractName) {
}
/**
* retrieve memebers declared in the given @arg tye
* retrieve members declared in the given @arg tye
*
* @param {String} typeName - name of the struct type (e.g struct <name>)
* @param {Object} stateDefinitions - all state definition given by the AST (including struct and enum type declaration) for all contracts
@ -264,7 +264,7 @@ function getStructMembers (type, stateDefinitions, contractName, location) {
* parse the full type
*
* @param {String} fullType - type given by the AST (ex: uint[2] storage ref[2])
* @return {String} returns the token type (used to instanciate the right decoder) (uint[2] storage ref[2] will return 'array', uint256 will return uintX)
* @return {String} returns the token type (used to instantiate the right decoder) (uint[2] storage ref[2] will return 'array', uint256 will return uintX)
*/
function typeClass (fullType) {
fullType = removeLocation(fullType)

@ -122,7 +122,7 @@ export class SolidityProxy {
}
/**
* get the filename refering to the index from the compilation result
* get the filename referring to the index from the compilation result
*
* @param {Int} index - index of the filename
* @param {Object} compilationResult - current compilation result

@ -4,11 +4,11 @@ import { getLinebreakPositions, convertOffsetToLineColumn } from './sourceMappin
export class OffsetToColumnConverter {
lineBreakPositionsByContent
sourceMappingDecoder
offsetConvertion
offsetConversion
constructor (compilerEvent) {
this.lineBreakPositionsByContent = {}
this.offsetConvertion = {}
this.offsetConversion = {}
if (compilerEvent) {
compilerEvent.register('compilationFinished', (success, data, source, input, version) => {
this.clear()
@ -29,17 +29,17 @@ export class OffsetToColumnConverter {
}
}
const token = `${rawLocation.start}:${rawLocation.length}:${file}`
if (this.offsetConvertion[token]) {
return this.offsetConvertion[token]
if (this.offsetConversion[token]) {
return this.offsetConversion[token]
} else {
const convertion = convertOffsetToLineColumn(rawLocation, this.lineBreakPositionsByContent[file])
this.offsetConvertion[token] = convertion
return convertion
const conversion = convertOffsetToLineColumn(rawLocation, this.lineBreakPositionsByContent[file])
this.offsetConversion[token] = conversion
return conversion
}
}
clear () {
this.lineBreakPositionsByContent = {}
this.offsetConvertion = {}
this.offsetConversion = {}
}
}

@ -5,7 +5,7 @@ import { sub } from '../solidity-decoder/types/util'
* like { "<mapping_slot>" : { "<mapping-key1>": preimageOf1 }, { "<mapping-key2>": preimageOf2 }, ... }
*
* @param {Object} storage - storage given by storage Viewer (basically a mapping hashedkey : {key, value})
* @param {Array} corrections - used in case the calculated sha3 has been modifyed before SSTORE (notably used for struct in mapping).
* @param {Array} corrections - used in case the calculated sha3 has been modified before SSTORE (notably used for struct in mapping).
* @param {Function} callback - callback
* @return {Map} - solidity mapping location (e.g { "<mapping_slot>" : { "<mapping-key1>": preimageOf1 }, { "<mapping-key2>": preimageOf2 }, ... })
*/

@ -35,13 +35,13 @@ export class StorageResolver {
}
/**
* compute the mappgings type locations for the current address (cached for a debugging session)
* compute the mappings type locations for the current address (cached for a debugging session)
* note: that only retrieve the first 100 items.
*
* @param {Object} tx
* @param {Int} stepIndex
* @param {Object} address - storage
* @param {Array} corrections - used in case the calculated sha3 has been modifyed before SSTORE (notably used for struct in mapping).
* @param {Array} corrections - used in case the calculated sha3 has been modified before SSTORE (notably used for struct in mapping).
* @return {Function} - callback
*/
async initialPreimagesMappings (tx, stepIndex, address, corrections) {

@ -40,7 +40,7 @@ export class TraceCache {
this.memoryChanges = []
this.formattedMemory = {}
this.storageChanges = []
this.sstore = {} // all sstore occurence in the trace
this.sstore = {} // all sstore occurrences in the trace
}
pushSteps (index, currentCallIndex) {

@ -1,4 +1,4 @@
// TODO: this file shoudl be removed at some point
// TODO: this file should be removed at some point
const CmdLine = require('./src/cmdline/index')
// var compilation = require('./compilation.json')

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-lib",
"version": "0.5.49",
"version": "0.5.50",
"description": "Library to various Remix tools",
"contributors": [
{
@ -55,6 +55,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme",
"typings": "src/index.d.ts",
"gitHead": "817089ab1f206f5e195756a4051afb812ec26901",
"gitHead": "d08019670b3095207b262dac71c55d8467a81f85",
"types": "./src/index.d.ts"
}

@ -80,7 +80,7 @@ export function checkError (execResult, compiledContracts) {
return ret
}
const exceptionError = execResult.errorMessage || ''
const error = `Error occured: ${execResult.errorMessage}.\n`
const error = `Error occurred: ${execResult.errorMessage}.\n`
let msg = ''
if (exceptionError.includes(errorCode.INVALID_OPCODE)) {
msg = '\t\n\tThe execution might have thrown OR the EVM version used by the selected environment is not compatible with the compiler EVM version.\n'
@ -113,7 +113,7 @@ export function checkError (execResult, compiledContracts) {
const decodedCustomErrorInputs = fn.decodeFunctionData(functionDesc, returnData)
decodedCustomErrorInputsClean = {}
let devdoc = {}
// "contract" reprensents the compilation result containing the NATSPEC documentation
// "contract" represents the compilation result containing the NATSPEC documentation
if (contract && fn.functions && Object.keys(fn.functions).length) {
const functionSignature = Object.keys(fn.functions)[0]
// we check in the 'devdoc' if there's a developer documentation for this error

@ -32,7 +32,7 @@ export function encodeData (funABI, values, contractbyteCode) {
/**
* encode function / constructor parameters
*
* @param {Object} params - input paramater of the function to call
* @param {Object} params - input parameter of the function to call
* @param {Object} funAbi - abi definition of the function to call. null if building data for the ctor.
* @param {Function} callback - callback
*/
@ -94,7 +94,7 @@ export function encodeParams (params, funAbi, callback?) {
/**
* encode function call (function id + encoded parameters)
*
* @param {Object} params - input paramater of the function to call
* @param {Object} params - input parameter of the function to call
* @param {Object} funAbi - abi definition of the function to call. null if building data for the ctor.
* @param {Function} callback - callback
*/
@ -108,8 +108,8 @@ export function encodeFunctionCall (params, funAbi, callback) {
/**
* encode constructor creation and link with provided libraries if needed
*
* @param {Object} contract - input paramater of the function to call
* @param {Object} params - input paramater of the function to call
* @param {Object} contract - input parameter of the function to call
* @param {Object} params - input parameter of the function to call
* @param {Object} funAbi - abi definition of the function to call. null if building data for the ctor.
* @param {Object} linkLibraries - contains {linkReferences} object which list all the addresses to be linked
* @param {Object} linkReferences - given by the compiler, contains the proper linkReferences
@ -127,7 +127,7 @@ export function encodeConstructorCallAndLinkLibraries (contract, params, funAbi,
/**
* link with provided libraries if needed
*
* @param {Object} contract - input paramater of the function to call
* @param {Object} contract - input parameter of the function to call
* @param {Object} linkLibraries - contains {linkReferences} object which list all the addresses to be linked
* @param {Object} linkReferences - given by the compiler, contains the proper linkReferences
* @param {Function} callback - callback
@ -152,12 +152,12 @@ export function linkLibraries (contract, linkLibraries, linkReferences, callback
}
/**
* encode constructor creation and deploy librairies if needed
* encode constructor creation and deploy libraries if needed
*
* @param {String} contractName - current contract name
* @param {Object} contract - input paramater of the function to call
* @param {Object} contract - input parameter of the function to call
* @param {Object} contracts - map of all compiled contracts.
* @param {Object} params - input paramater of the function to call
* @param {Object} params - input parameter of the function to call
* @param {Object} funAbi - abi definition of the function to call. null if building data for the ctor.
* @param {Function} callback - callback
* @param {Function} callbackStep - callbackStep
@ -195,7 +195,7 @@ export function encodeConstructorCallAndDeployLibraries (contractName, contract,
* @param {Object} contracts - map of all compiled contracts.
* @param {Bool} isConstructor - isConstructor.
* @param {Object} funAbi - abi definition of the function to call. null if building data for the ctor.
* @param {Object} params - input paramater of the function to call
* @param {Object} params - input parameter of the function to call
* @param {Function} callback - callback
* @param {Function} callbackStep - callbackStep
* @param {Function} callbackDeployLibrary - callbackDeployLibrary
@ -399,7 +399,7 @@ export function decodeResponse (response, fnabi) {
const type = fnabi.outputs[i].type
outputTypes.push(type.indexOf('tuple') === 0 ? makeFullTypeDefinition(fnabi.outputs[i]) : type)
}
if (!response || !response.length) response = new Uint8Array(32 * fnabi.outputs.length) // ensuring the data is at least filled by 0 cause `AbiCoder` throws if there's not engouh data
if (!response || !response.length) response = new Uint8Array(32 * fnabi.outputs.length) // ensuring the data is at least filled by 0 cause `AbiCoder` throws if there's not enough data
// decode data
const abiCoder = new ethers.utils.AbiCoder()
const decodedObj = abiCoder.decode(outputTypes, response)

@ -375,7 +375,7 @@ export class TxListener {
_decodeInputParams (data, abi) {
data = toBuffer(addHexPrefix(data))
if (!data.length) data = new Uint8Array(32 * abi.inputs.length) // ensuring the data is at least filled by 0 cause `AbiCoder` throws if there's not engouh data
if (!data.length) data = new Uint8Array(32 * abi.inputs.length) // ensuring the data is at least filled by 0 cause `AbiCoder` throws if there's not enough data
const inputTypes = []
for (let i = 0; i < abi.inputs.length; i++) {

@ -181,7 +181,7 @@ async function tryTillReceiptAvailable (txhash: string, web3: Web3) {
if (receipt) {
if (!receipt.to && !receipt.contractAddress) {
// this is a contract creation and the receipt doesn't contain a contract address. we have to keep polling...
console.log('this is a contract creation and the receipt does nott contain a contract address. we have to keep polling...')
console.log('this is a contract creation and the receipt does not contain a contract address. we have to keep polling...')
} else
return receipt
}

@ -24,7 +24,7 @@ export const keccak = function(a: Buffer, bits: number = 256): Buffer {
return toBuffer(keccak512(a))
}
default: {
throw new Error(`Invald algorithm: keccak${bits}`)
throw new Error(`Invalid algorithm: keccak${bits}`)
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save