Merge branch 'master' into modal-check

pull/5370/head
bunsenstraat 2 years ago committed by GitHub
commit d2b3c67f18
  1. 233
      .circleci/config.yml
  2. 19
      apps/remix-ide-e2e/src/commands/addFile.ts
  3. 587
      apps/remix-ide-e2e/src/helpers/foundry_compilation.json
  4. 1
      apps/remix-ide-e2e/src/helpers/hardhat_compilation.ts
  5. 4
      apps/remix-ide-e2e/src/helpers/init.ts
  6. 878
      apps/remix-ide-e2e/src/helpers/truffle_compilation.json
  7. 49
      apps/remix-ide-e2e/src/tests/ballot.test.ts
  8. 38
      apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts
  9. 6
      apps/remix-ide-e2e/src/tests/generalSettings.test.ts
  10. 48
      apps/remix-ide-e2e/src/tests/remixd.test.ts
  11. 1
      apps/remix-ide/contracts/build/contracts/.gitignore
  12. 6
      apps/remix-ide/contracts/foundry.toml
  13. 266
      apps/remix-ide/contracts/out/Counter.s.sol/CounterScript.json
  14. 121
      apps/remix-ide/contracts/out/Counter.s.sol/CounterScript.metadata.json
  15. 587
      apps/remix-ide/contracts/out/Counter.sol/Counter.json
  16. 82
      apps/remix-ide/contracts/out/Counter.sol/Counter.metadata.json
  17. 1310
      apps/remix-ide/contracts/out/Counter.t.sol/CounterTest.json
  18. 561
      apps/remix-ide/contracts/out/Counter.t.sol/CounterTest.metadata.json
  19. 3630
      apps/remix-ide/contracts/out/Script.sol/Script.json
  20. 99
      apps/remix-ide/contracts/out/Script.sol/Script.metadata.json
  21. 37681
      apps/remix-ide/contracts/out/Test.sol/Test.json
  22. 505
      apps/remix-ide/contracts/out/Test.sol/Test.metadata.json
  23. 37401
      apps/remix-ide/contracts/out/Test.sol/stdError.json
  24. 219
      apps/remix-ide/contracts/out/Test.sol/stdError.metadata.json
  25. 37259
      apps/remix-ide/contracts/out/Test.sol/stdMath.json
  26. 88
      apps/remix-ide/contracts/out/Test.sol/stdMath.metadata.json
  27. 37336
      apps/remix-ide/contracts/out/Test.sol/stdStorage.json
  28. 163
      apps/remix-ide/contracts/out/Test.sol/stdStorage.metadata.json
  29. 9179
      apps/remix-ide/contracts/out/Vm.sol/Vm.json
  30. 1669
      apps/remix-ide/contracts/out/Vm.sol/Vm.metadata.json
  31. 110819
      apps/remix-ide/contracts/out/console.sol/console.json
  32. 48
      apps/remix-ide/contracts/out/console.sol/console.metadata.json
  33. 110818
      apps/remix-ide/contracts/out/console2.sol/console2.json
  34. 48
      apps/remix-ide/contracts/out/console2.sol/console2.metadata.json
  35. 23370
      apps/remix-ide/contracts/out/test.sol/DSTest.json
  36. 343
      apps/remix-ide/contracts/out/test.sol/DSTest.metadata.json
  37. 1
      apps/remix-ide/contracts/truffle-config.js
  38. 16
      apps/remix-ide/src/app.js
  39. 18
      apps/remix-ide/src/app/files/foundry-handle.js
  40. 2
      apps/remix-ide/src/app/panels/file-panel.js
  41. 82
      apps/remix-ide/src/app/plugins/code-format.ts
  42. 61
      apps/remix-ide/src/app/plugins/code-format/index.ts
  43. 197
      apps/remix-ide/src/app/plugins/code-format/parser.ts
  44. 26
      apps/remix-ide/src/app/plugins/parser/code-parser.tsx
  45. 92
      apps/remix-ide/src/app/plugins/parser/services/code-parser-compiler.ts
  46. 82
      apps/remix-ide/src/app/plugins/parser/services/code-parser-imports.ts
  47. 2
      apps/remix-ide/src/app/plugins/remixd-handle.tsx
  48. 8
      apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css
  49. 4
      apps/remix-ide/src/assets/css/themes/bootstrap-flatly.min.css
  50. 4
      apps/remix-ide/src/assets/css/themes/bootstrap-spacelab.min.css
  51. 2
      apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css
  52. 2
      apps/remix-ide/src/remixAppManager.js
  53. 10
      libs/remix-core-plugin/src/lib/compiler-artefacts.ts
  54. 99
      libs/remix-ui/editor/src/lib/providers/completion/completionGlobals.ts
  55. 198
      libs/remix-ui/editor/src/lib/providers/completion/contracts/contracts.txt
  56. 38
      libs/remix-ui/editor/src/lib/providers/completionProvider.ts
  57. 18
      libs/remix-ui/editor/src/lib/providers/definitionProvider.ts
  58. 27
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  59. 2
      libs/remix-ui/panel/src/lib/plugins/remix-ui-panel.tsx
  60. 2
      libs/remix-ui/permission-handler/src/lib/permission-dialog.tsx
  61. 4
      libs/remix-ui/run-tab/src/lib/actions/events.ts
  62. 2
      libs/remix-ui/search/src/index.ts
  63. 4
      libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx
  64. 2
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
  65. 2
      libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css
  66. 19
      libs/remixd/src/bin/remixd.ts
  67. 1
      libs/remixd/src/serviceList.ts
  68. 138
      libs/remixd/src/services/foundryClient.ts
  69. 13
      libs/remixd/src/services/hardhatClient.ts
  70. 81
      libs/remixd/src/services/truffleClient.ts
  71. 3
      libs/remixd/src/websocket.ts
  72. 9
      package.json
  73. 78
      yarn.lock

@ -8,17 +8,19 @@ parameters:
type: boolean
default: false
orbs:
browser-tools: circleci/browser-tools@1.3.0
browser-tools: circleci/browser-tools@1.4.0
node: circleci/node@5.0.2
jobs:
build:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
@ -26,11 +28,13 @@ jobs:
working_directory: ~/remix-project
steps:
- checkout
- node/install:
install-yarn: true
node-version: "v14.17.6"
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: yarn
- save_cache:
key: v1-deps-{{ checksum "yarn.lock" }}
paths:
@ -44,16 +48,17 @@ jobs:
- persist_to_workspace:
root: .
paths:
- 'persist'
- "persist"
lint:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
@ -62,22 +67,26 @@ jobs:
parallelism: 35
steps:
- checkout
- node/install:
install-yarn: true
node-version: "v14.17.6"
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: yarn
- run:
name: Remix Libs Linting
command: ./apps/remix-ide/ci/lint.sh
remix-libs:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
@ -86,40 +95,46 @@ jobs:
steps:
- checkout
- node/install:
install-yarn: true
node-version: "v14.17.6"
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: cd dist/libs/remix-tests && yarn install
- run: yarn
- run: cd dist/libs/remix-tests && yarn
- run: yarn run test:libs
remix-ide-chrome:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project
parallelism: 80
parallelism: 95
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run:
command: |
google-chrome --version
chromedriver --version
java -jar /usr/local/bin/selenium.jar --version
name: Check install
- checkout
- attach_workspace:
@ -128,10 +143,16 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: ./apps/remix-ide/ci/browser_test.sh chrome
- store_test_results:
@ -142,27 +163,30 @@ jobs:
flaky-chrome:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project
parallelism: 80
parallelism: 95
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run:
command: |
google-chrome --version
chromedriver --version
java -jar /usr/local/bin/selenium.jar --version
name: Check install
- checkout
- attach_workspace:
@ -171,10 +195,16 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: ./apps/remix-ide/ci/flaky.sh chrome
- store_test_results:
@ -185,27 +215,31 @@ jobs:
remix-ide-firefox:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project
parallelism: 80
parallelism: 95
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-firefox
- browser-tools/install-geckodriver
- run:
command: |
firefox --version
geckodriver --version
java -jar /usr/local/bin/selenium.jar --version
name: Check install
- checkout
- attach_workspace:
@ -214,10 +248,16 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: ./apps/remix-ide/ci/browser_test.sh firefox
- store_test_results:
@ -227,27 +267,31 @@ jobs:
flaky-firefox:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project
parallelism: 80
parallelism: 95
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-firefox
- browser-tools/install-geckodriver
- run:
command: |
firefox --version
geckodriver --version
java -jar /usr/local/bin/selenium.jar --version
name: Check install
- checkout
- attach_workspace:
@ -256,10 +300,16 @@ jobs:
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: ./apps/remix-ide/ci/flaky.sh firefox
- store_test_results:
@ -270,12 +320,13 @@ jobs:
remix-ide-vyper-plugin:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
@ -283,26 +334,34 @@ jobs:
working_directory: ~/remix-project
parallelism: 10
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run:
command: |
google-chrome --version
chromedriver --version
java -jar /usr/local/bin/selenium.jar --version
name: Check install
- checkout
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: yarn
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: npx nx build vyper
- run: ./apps/remix-ide/ci/browser_tests_vyper_plugin.sh
@ -314,12 +373,13 @@ jobs:
remix-ide-etherscan-plugin:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
@ -327,26 +387,34 @@ jobs:
working_directory: ~/remix-project
parallelism: 10
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run:
command: |
google-chrome --version
chromedriver --version
java -jar /usr/local/bin/selenium.jar --version
name: Check install
- checkout
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Install Selenium
command: yarn run selenium-install
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
name: Run Selenium
command: yarn run selenium
background: true
- run: npx nx build etherscan
- run: ./apps/remix-ide/ci/browser_tests_etherscan_plugin.sh
@ -358,12 +426,13 @@ jobs:
remix-ide-plugin-api:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
@ -371,26 +440,34 @@ jobs:
working_directory: ~/remix-project
parallelism: 10
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run:
command: |
google-chrome --version
chromedriver --version
java -jar /usr/local/bin/selenium.jar --version
name: Check install
- checkout
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: ./apps/remix-ide/ci/browser_tests_plugin_api.sh
- store_test_results:
@ -401,12 +478,13 @@ jobs:
deploy-remix-live:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
@ -416,7 +494,10 @@ jobs:
steps:
- checkout
- run: yarn install
- node/install:
install-yarn: true
node-version: "v14.17.6"
- run: yarn
- run: yarn run downloadsolc_assets
- run: yarn run build:production
- run:
@ -426,15 +507,15 @@ jobs:
./apps/remix-ide/ci/deploy_from_travis_remix-live.sh;
fi
deploy-remix-alpha:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
resource_class: xlarge
resource_class:
xlarge
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
environment:
@ -445,7 +526,10 @@ jobs:
steps:
- checkout
- run: yarn install
- node/install:
install-yarn: true
node-version: "v14.17.6"
- run: yarn
- run: yarn run downloadsolc_assets
- run: yarn run build:production
- run:
@ -458,11 +542,12 @@ jobs:
deploy-remix-beta:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
resource_class: xlarge
resource_class:
xlarge
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
environment:
@ -473,7 +558,10 @@ jobs:
steps:
- checkout
- run: yarn install
- node/install:
install-yarn: true
node-version: "v14.17.6"
- run: yarn
- run: yarn run build:libs
- run: yarn run downloadsolc_assets
- run: yarn run build:production
@ -556,4 +644,3 @@ workflows:
filters:
branches:
only: remix_beta

@ -2,7 +2,7 @@ import { NightwatchBrowser, NightwatchContractContent } from 'nightwatch'
import EventEmitter from 'events'
class AddFile extends EventEmitter {
command (this: NightwatchBrowser, name: string, content: NightwatchContractContent): NightwatchBrowser {
command(this: NightwatchBrowser, name: string, content: NightwatchContractContent): NightwatchBrowser {
this.api.perform((done) => {
addFile(this.api, name, content, () => {
done()
@ -14,8 +14,21 @@ class AddFile extends EventEmitter {
}
function addFile (browser: NightwatchBrowser, name: string, content: NightwatchContractContent, done: VoidFunction) {
browser.clickLaunchIcon('udapp')
.clickLaunchIcon('filePanel')
browser
.saveScreenshot('./reports/screenshots/addFile.png')
.isVisible({
selector: "//*[@data-id='sidePanelSwapitTitle' and contains(.,'File explorer')]",
locateStrategy: 'xpath',
suppressNotFoundErrors: true,
timeout: 1000
}, (okVisible) => {
if (!okVisible.value) {
browser.clickLaunchIcon('filePanel')
.saveScreenshot('./reports/screenshots/addFile2.png')
}
})
.scrollInto('li[data-id="treeViewLitreeViewItemREADME.txt"]')
.saveScreenshot('./reports/screenshots/addFile3.png')
.waitForElementVisible('li[data-id="treeViewLitreeViewItemREADME.txt"]')
.click('li[data-id="treeViewLitreeViewItemREADME.txt"]').pause(1000) // focus on root directory
.elements('css selector', `li[data-id="treeViewLitreeViewItem${name}"]`, (res) => {

@ -0,0 +1,587 @@
{
"abi": [
{
"inputs": [],
"name": "increment",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "number",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newNumber",
"type": "uint256"
}
],
"name": "setNumber",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": {
"object": "0x608060405234801561001057600080fd5b50610125806100206000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146052578063d09de08a14606c575b600080fd5b6050604c3660046095565b6072565b005b605a60005481565b60405190815260200160405180910390f35b60506081565b607b81607b60c3565b60005550565b600080549080608e8360d9565b9190505550565b60006020828403121560a657600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111560d35760d360ad565b92915050565b60006001820160e85760e860ad565b506001019056fea2646970667358221220981d705d73c405a1cadf6bcd0ff9f1d0fcbbc1599040e504e71517ff0d8aa53264736f6c63430008100033",
"sourceMap": "65:198:7:-:0;;;;;;;;;;;;;;;;;;;",
"linkReferences": {}
},
"deployedBytecode": {
"object": "0x6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146052578063d09de08a14606c575b600080fd5b6050604c3660046095565b6072565b005b605a60005481565b60405190815260200160405180910390f35b60506081565b607b81607b60c3565b60005550565b600080549080608e8360d9565b9190505550565b60006020828403121560a657600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111560d35760d360ad565b92915050565b60006001820160e85760e860ad565b506001019056fea2646970667358221220981d705d73c405a1cadf6bcd0ff9f1d0fcbbc1599040e504e71517ff0d8aa53264736f6c63430008100033",
"sourceMap": "65:198:7:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116:86;;;;;;:::i;:::-;;:::i;:::-;;88:21;;;;;;;;;345:25:9;;;333:2;318:18;88:21:7;;;;;;;208:53;;;:::i;116:86::-;180:15;:9;192:3;180:15;:::i;:::-;171:6;:24;-1:-1:-1;116:86:7:o;208:53::-;246:6;:8;;;:6;:8;;;:::i;:::-;;;;;;208:53::o;14:180:9:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:9;;14:180;-1:-1:-1;14:180:9:o;381:127::-;442:10;437:3;433:20;430:1;423:31;473:4;470:1;463:15;497:4;494:1;487:15;513:125;578:9;;;599:10;;;596:36;;;612:18;;:::i;:::-;513:125;;;;:::o;643:135::-;682:3;703:17;;;700:43;;723:18;;:::i;:::-;-1:-1:-1;770:1:9;759:13;;643:135::o",
"linkReferences": {}
},
"methodIdentifiers": {
"increment()": "d09de08a",
"number()": "8381f58a",
"setNumber(uint256)": "3fb5c1cb"
},
"ast": {
"absolutePath": "src/Counter.sol",
"id": 21628,
"exportedSymbols": {
"Counter": [
21605
],
"CounterYann": [
21627
]
},
"nodeType": "SourceUnit",
"src": "39:427:7",
"nodes": [
{
"id": 21583,
"nodeType": "PragmaDirective",
"src": "39:24:7",
"literals": [
"solidity",
"^",
"0.8",
".13"
]
},
{
"id": 21605,
"nodeType": "ContractDefinition",
"src": "65:198:7",
"nodes": [
{
"id": 21585,
"nodeType": "VariableDeclaration",
"src": "88:21:7",
"constant": false,
"functionSelector": "8381f58a",
"mutability": "mutable",
"name": "number",
"nameLocation": "103:6:7",
"scope": 21605,
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 21584,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "88:7:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"visibility": "public"
},
{
"id": 21597,
"nodeType": "FunctionDefinition",
"src": "116:86:7",
"body": {
"id": 21596,
"nodeType": "Block",
"src": "161:41:7",
"statements": [
{
"expression": {
"id": 21594,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"id": 21590,
"name": "number",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21585,
"src": "171:6:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 21593,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"id": 21591,
"name": "newNumber",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21587,
"src": "180:9:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": "+",
"rightExpression": {
"hexValue": "313233",
"id": 21592,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "192:3:7",
"typeDescriptions": {
"typeIdentifier": "t_rational_123_by_1",
"typeString": "int_const 123"
},
"value": "123"
},
"src": "180:15:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "171:24:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 21595,
"nodeType": "ExpressionStatement",
"src": "171:24:7"
}
]
},
"functionSelector": "3fb5c1cb",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "setNumber",
"nameLocation": "125:9:7",
"parameters": {
"id": 21588,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 21587,
"mutability": "mutable",
"name": "newNumber",
"nameLocation": "143:9:7",
"nodeType": "VariableDeclaration",
"scope": 21597,
"src": "135:17:7",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 21586,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "135:7:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"visibility": "internal"
}
],
"src": "134:19:7"
},
"returnParameters": {
"id": 21589,
"nodeType": "ParameterList",
"parameters": [],
"src": "161:0:7"
},
"scope": 21605,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
},
{
"id": 21604,
"nodeType": "FunctionDefinition",
"src": "208:53:7",
"body": {
"id": 21603,
"nodeType": "Block",
"src": "236:25:7",
"statements": [
{
"expression": {
"id": 21601,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"nodeType": "UnaryOperation",
"operator": "++",
"prefix": false,
"src": "246:8:7",
"subExpression": {
"id": 21600,
"name": "number",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21585,
"src": "246:6:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 21602,
"nodeType": "ExpressionStatement",
"src": "246:8:7"
}
]
},
"functionSelector": "d09de08a",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "increment",
"nameLocation": "217:9:7",
"parameters": {
"id": 21598,
"nodeType": "ParameterList",
"parameters": [],
"src": "226:2:7"
},
"returnParameters": {
"id": 21599,
"nodeType": "ParameterList",
"parameters": [],
"src": "236:0:7"
},
"scope": 21605,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"abstract": false,
"baseContracts": [],
"canonicalName": "Counter",
"contractDependencies": [],
"contractKind": "contract",
"fullyImplemented": true,
"linearizedBaseContracts": [
21605
],
"name": "Counter",
"nameLocation": "74:7:7",
"scope": 21628,
"usedErrors": []
},
{
"id": 21627,
"nodeType": "ContractDefinition",
"src": "265:200:7",
"nodes": [
{
"id": 21607,
"nodeType": "VariableDeclaration",
"src": "292:21:7",
"constant": false,
"functionSelector": "8381f58a",
"mutability": "mutable",
"name": "number",
"nameLocation": "307:6:7",
"scope": 21627,
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 21606,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "292:7:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"visibility": "public"
},
{
"id": 21619,
"nodeType": "FunctionDefinition",
"src": "320:84:7",
"body": {
"id": 21618,
"nodeType": "Block",
"src": "365:39:7",
"statements": [
{
"expression": {
"id": 21616,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"id": 21612,
"name": "number",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21607,
"src": "375:6:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 21615,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"id": 21613,
"name": "newNumber",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21609,
"src": "384:9:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": "+",
"rightExpression": {
"hexValue": "39",
"id": 21614,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "396:1:7",
"typeDescriptions": {
"typeIdentifier": "t_rational_9_by_1",
"typeString": "int_const 9"
},
"value": "9"
},
"src": "384:13:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "375:22:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 21617,
"nodeType": "ExpressionStatement",
"src": "375:22:7"
}
]
},
"functionSelector": "3fb5c1cb",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "setNumber",
"nameLocation": "329:9:7",
"parameters": {
"id": 21610,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 21609,
"mutability": "mutable",
"name": "newNumber",
"nameLocation": "347:9:7",
"nodeType": "VariableDeclaration",
"scope": 21619,
"src": "339:17:7",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 21608,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "339:7:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"visibility": "internal"
}
],
"src": "338:19:7"
},
"returnParameters": {
"id": 21611,
"nodeType": "ParameterList",
"parameters": [],
"src": "365:0:7"
},
"scope": 21627,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
},
{
"id": 21626,
"nodeType": "FunctionDefinition",
"src": "410:53:7",
"body": {
"id": 21625,
"nodeType": "Block",
"src": "438:25:7",
"statements": [
{
"expression": {
"id": 21623,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"nodeType": "UnaryOperation",
"operator": "++",
"prefix": false,
"src": "448:8:7",
"subExpression": {
"id": 21622,
"name": "number",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21607,
"src": "448:6:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 21624,
"nodeType": "ExpressionStatement",
"src": "448:8:7"
}
]
},
"functionSelector": "d09de08a",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "increment",
"nameLocation": "419:9:7",
"parameters": {
"id": 21620,
"nodeType": "ParameterList",
"parameters": [],
"src": "428:2:7"
},
"returnParameters": {
"id": 21621,
"nodeType": "ParameterList",
"parameters": [],
"src": "438:0:7"
},
"scope": 21627,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"abstract": false,
"baseContracts": [],
"canonicalName": "CounterYann",
"contractDependencies": [],
"contractKind": "contract",
"fullyImplemented": true,
"linearizedBaseContracts": [
21627
],
"name": "CounterYann",
"nameLocation": "274:11:7",
"scope": 21628,
"usedErrors": []
}
],
"license": "UNLICENSED"
},
"id": 7
}

@ -24,8 +24,8 @@ export default function (browser: NightwatchBrowser, callback: VoidFunction, url
.pause(6000)
.perform(done())
})
.maximizeWindow()
.fullscreenWindow(() => {
//.maximizeWindow()
.perform(() => {
if (preloadPlugins) {
initModules(browser, () => {
browser.pause(2000).clickLaunchIcon('solidity')

@ -0,0 +1,878 @@
{
"contractName": "Migrations",
"abi": [
{
"constant": true,
"inputs": [],
"name": "last_completed_migration",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "uint256",
"name": "completed",
"type": "uint256"
}
],
"name": "setCompleted",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"last_completed_migration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"completed\",\"type\":\"uint256\"}],\"name\":\"setCompleted\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"/home/yann/truffletemp/contracts/Migrations.sol\":\"Migrations\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"/home/yann/truffletemp/contracts/Migrations.sol\":{\"keccak256\":\"0x7797e159bfd6b953422b4bd6d5de5946971d8b5ed74c4b1f6517d61fe236b851\",\"urls\":[\"bzz-raw://56bdf6130f3ced3e78baa0f3e7f34cb4c5131d90721326056bbf0dd202d8539d\",\"dweb:/ipfs/QmZqRKebKwn6YXejnnPribsyiXLmrAx32JpatFhvS76NKp\"]}},\"version\":1}",
"bytecode": "0x6080604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561005057600080fd5b5061021e806100606000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063445df0ac146100465780638da5cb5b14610064578063fdacd576146100ae575b600080fd5b61004e6100dc565b6040518082815260200191505060405180910390f35b61006c6100e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100da600480360360208110156100c457600080fd5b8101908080359060200190929190505050610107565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806101b76033913960400191505060405180910390fd5b806001819055505056fe546869732066756e6374696f6e206973207265737472696374656420746f2074686520636f6e74726163742773206f776e6572a265627a7a723158202d8ffeacea919d054933bfa385b1dba75680df6aee19f861fea56d15484b874764736f6c63430005100032",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063445df0ac146100465780638da5cb5b14610064578063fdacd576146100ae575b600080fd5b61004e6100dc565b6040518082815260200191505060405180910390f35b61006c6100e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100da600480360360208110156100c457600080fd5b8101908080359060200190929190505050610107565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806101b76033913960400191505060405180910390fd5b806001819055505056fe546869732066756e6374696f6e206973207265737472696374656420746f2074686520636f6e74726163742773206f776e6572a265627a7a723158202d8ffeacea919d054933bfa385b1dba75680df6aee19f861fea56d15484b874764736f6c63430005100032",
"sourceMap": "66:352:0:-;;;113:10;90:33;;;;;;;;;;;;;;;;;;;;66:352;8:9:-1;5:2;;;30:1;27;20:12;5:2;66:352:0;;;;;;;",
"deployedSourceMap": "66:352:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66:352:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;127:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;90:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;313:103;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;313:103:0;;;;;;;;;;;;;;;;;:::i;:::-;;127:36;;;;:::o;90:33::-;;;;;;;;;;;;;:::o;313:103::-;225:5;;;;;;;;;;;211:19;;:10;:19;;;196:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;402:9;375:24;:36;;;;313:103;:::o",
"source": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.8.0;\n\ncontract Migrations {\n address public owner = msg.sender;\n uint public last_completed_migration;\n\n modifier restricted() {\n require(\n msg.sender == owner,\n \"This function is restricted to the contract's owner\"\n );\n _;\n }\n\n function setCompleted(uint completed) public restricted {\n last_completed_migration = completed;\n }\n}\n",
"sourcePath": "/home/yann/truffletemp/contracts/Migrations.sol",
"ast": {
"absolutePath": "/home/yann/truffletemp/contracts/Migrations.sol",
"exportedSymbols": {
"Migrations": [
32
]
},
"id": 33,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1,
"literals": [
"solidity",
">=",
"0.4",
".22",
"<",
"0.8",
".0"
],
"nodeType": "PragmaDirective",
"src": "32:32:0"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 32,
"linearizedBaseContracts": [
32
],
"name": "Migrations",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 5,
"name": "owner",
"nodeType": "VariableDeclaration",
"scope": 32,
"src": "90:33:0",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 2,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "90:7:0",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 3,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 47,
"src": "113:3:0",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 4,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "113:10:0",
"typeDescriptions": {
"typeIdentifier": "t_address_payable",
"typeString": "address payable"
}
},
"visibility": "public"
},
{
"constant": false,
"id": 7,
"name": "last_completed_migration",
"nodeType": "VariableDeclaration",
"scope": 32,
"src": "127:36:0",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 6,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "127:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "public"
},
{
"body": {
"id": 18,
"nodeType": "Block",
"src": "190:119:0",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 13,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 10,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 47,
"src": "211:3:0",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 11,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "211:10:0",
"typeDescriptions": {
"typeIdentifier": "t_address_payable",
"typeString": "address payable"
}
},
"nodeType": "BinaryOperation",
"operator": "==",
"rightExpression": {
"argumentTypes": null,
"id": 12,
"name": "owner",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 5,
"src": "225:5:0",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "211:19:0",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "546869732066756e6374696f6e206973207265737472696374656420746f2074686520636f6e74726163742773206f776e6572",
"id": 14,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "238:53:0",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_f60fe2d9d123295bf92ecf95167f1fa709e374da35e4c083bd39dc2d82acd8b1",
"typeString": "literal_string \"This function is restricted to the contract's owner\""
},
"value": "This function is restricted to the contract's owner"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_f60fe2d9d123295bf92ecf95167f1fa709e374da35e4c083bd39dc2d82acd8b1",
"typeString": "literal_string \"This function is restricted to the contract's owner\""
}
],
"id": 9,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
50,
51
],
"referencedDeclaration": 51,
"src": "196:7:0",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 15,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "196:101:0",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 16,
"nodeType": "ExpressionStatement",
"src": "196:101:0"
},
{
"id": 17,
"nodeType": "PlaceholderStatement",
"src": "303:1:0"
}
]
},
"documentation": null,
"id": 19,
"name": "restricted",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 8,
"nodeType": "ParameterList",
"parameters": [],
"src": "187:2:0"
},
"src": "168:141:0",
"visibility": "internal"
},
{
"body": {
"id": 30,
"nodeType": "Block",
"src": "369:47:0",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 28,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 26,
"name": "last_completed_migration",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 7,
"src": "375:24:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 27,
"name": "completed",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21,
"src": "402:9:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "375:36:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 29,
"nodeType": "ExpressionStatement",
"src": "375:36:0"
}
]
},
"documentation": null,
"id": 31,
"implemented": true,
"kind": "function",
"modifiers": [
{
"arguments": null,
"id": 24,
"modifierName": {
"argumentTypes": null,
"id": 23,
"name": "restricted",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 19,
"src": "358:10:0",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "358:10:0"
}
],
"name": "setCompleted",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 22,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 21,
"name": "completed",
"nodeType": "VariableDeclaration",
"scope": 31,
"src": "335:14:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 20,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "335:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "334:16:0"
},
"returnParameters": {
"id": 25,
"nodeType": "ParameterList",
"parameters": [],
"src": "369:0:0"
},
"scope": 32,
"src": "313:103:0",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 33,
"src": "66:352:0"
}
],
"src": "32:387:0"
},
"legacyAST": {
"absolutePath": "/home/yann/truffletemp/contracts/Migrations.sol",
"exportedSymbols": {
"Migrations": [
32
]
},
"id": 33,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1,
"literals": [
"solidity",
">=",
"0.4",
".22",
"<",
"0.8",
".0"
],
"nodeType": "PragmaDirective",
"src": "32:32:0"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 32,
"linearizedBaseContracts": [
32
],
"name": "Migrations",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 5,
"name": "owner",
"nodeType": "VariableDeclaration",
"scope": 32,
"src": "90:33:0",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 2,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "90:7:0",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 3,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 47,
"src": "113:3:0",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 4,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "113:10:0",
"typeDescriptions": {
"typeIdentifier": "t_address_payable",
"typeString": "address payable"
}
},
"visibility": "public"
},
{
"constant": false,
"id": 7,
"name": "last_completed_migration",
"nodeType": "VariableDeclaration",
"scope": 32,
"src": "127:36:0",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 6,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "127:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "public"
},
{
"body": {
"id": 18,
"nodeType": "Block",
"src": "190:119:0",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 13,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 10,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 47,
"src": "211:3:0",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 11,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "211:10:0",
"typeDescriptions": {
"typeIdentifier": "t_address_payable",
"typeString": "address payable"
}
},
"nodeType": "BinaryOperation",
"operator": "==",
"rightExpression": {
"argumentTypes": null,
"id": 12,
"name": "owner",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 5,
"src": "225:5:0",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "211:19:0",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "546869732066756e6374696f6e206973207265737472696374656420746f2074686520636f6e74726163742773206f776e6572",
"id": 14,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "238:53:0",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_f60fe2d9d123295bf92ecf95167f1fa709e374da35e4c083bd39dc2d82acd8b1",
"typeString": "literal_string \"This function is restricted to the contract's owner\""
},
"value": "This function is restricted to the contract's owner"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_f60fe2d9d123295bf92ecf95167f1fa709e374da35e4c083bd39dc2d82acd8b1",
"typeString": "literal_string \"This function is restricted to the contract's owner\""
}
],
"id": 9,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
50,
51
],
"referencedDeclaration": 51,
"src": "196:7:0",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 15,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "196:101:0",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 16,
"nodeType": "ExpressionStatement",
"src": "196:101:0"
},
{
"id": 17,
"nodeType": "PlaceholderStatement",
"src": "303:1:0"
}
]
},
"documentation": null,
"id": 19,
"name": "restricted",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 8,
"nodeType": "ParameterList",
"parameters": [],
"src": "187:2:0"
},
"src": "168:141:0",
"visibility": "internal"
},
{
"body": {
"id": 30,
"nodeType": "Block",
"src": "369:47:0",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 28,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 26,
"name": "last_completed_migration",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 7,
"src": "375:24:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 27,
"name": "completed",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21,
"src": "402:9:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "375:36:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 29,
"nodeType": "ExpressionStatement",
"src": "375:36:0"
}
]
},
"documentation": null,
"id": 31,
"implemented": true,
"kind": "function",
"modifiers": [
{
"arguments": null,
"id": 24,
"modifierName": {
"argumentTypes": null,
"id": 23,
"name": "restricted",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 19,
"src": "358:10:0",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "358:10:0"
}
],
"name": "setCompleted",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 22,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 21,
"name": "completed",
"nodeType": "VariableDeclaration",
"scope": 31,
"src": "335:14:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 20,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "335:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "334:16:0"
},
"returnParameters": {
"id": 25,
"nodeType": "ParameterList",
"parameters": [],
"src": "369:0:0"
},
"scope": 32,
"src": "313:103:0",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 33,
"src": "66:352:0"
}
],
"src": "32:387:0"
},
"compiler": {
"name": "solc",
"version": "0.5.16+commit.9c3226ce.Emscripten.clang"
},
"networks": {},
"schemaVersion": "3.3.2",
"updatedAt": "2022-09-14T10:36:42.523Z",
"devdoc": {
"methods": {}
},
"userdoc": {
"methods": {}
}
}

@ -9,13 +9,18 @@ const sources = [
]
module.exports = {
"@disabled": true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},
'@sources': function () {
return sources
},
'Deploy Ballot': function (browser: NightwatchBrowser) {
'Add Ballot #group2': function (browser: NightwatchBrowser) {
browser
.addFile('Untitled.sol', sources[0]['Untitled.sol'])
},
'Deploy Ballot #group1': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.clickLaunchIcon('solidity')
@ -34,7 +39,7 @@ module.exports = {
})
},
'Call method from Ballot to check return value': function (browser: NightwatchBrowser) {
'Call method from Ballot to check return value #group1': function (browser: NightwatchBrowser) {
browser
.clickFunction('winnerName - call')
// Test in terminal
@ -47,7 +52,7 @@ module.exports = {
.assert.containsText('*[data-id="treeViewDiv0"]', 'bytes32: winnerName_ 0x48656c6c6f20576f726c64210000000000000000000000000000000000000000')
},
'Debug Ballot / delegate': function (browser: NightwatchBrowser) {
'Debug Ballot / delegate #group1': function (browser: NightwatchBrowser) {
browser.pause(500)
.debugTransaction(1)
.waitForElementVisible('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]')
@ -60,16 +65,24 @@ module.exports = {
.checkVariableDebug('soliditylocals', localsCheck)
},
'Access Ballot via at address': function (browser: NightwatchBrowser) {
'Access Ballot via at address #group1': function (browser: NightwatchBrowser) {
browser.clickLaunchIcon('udapp')
.click('*[data-id="universalDappUiUdappClose"]')
.addFile('ballot.abi', { content: ballotABI })
.clickLaunchIcon('udapp')
.click({
selector: '*[data-id="deployAndRunClearInstances"]',
abortOnFailure: false,
suppressNotFoundErrors: true,
})
// we are not changing the visibility for not checksumed contracts
// .addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3B', true, false)
.clickLaunchIcon('filePanel')
.addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3A', true, true)
.pause(500)
.waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]', 60000)
.waitForElementVisible({
locateStrategy: 'xpath',
selector: "//*[@id='instance0x692a70D2e424a56D2C6C27aA97D1a86395877b3A']"
})
.clickInstance(0)
.clickFunction('delegate - transact (not payable)', { types: 'address to', values: '"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db"' })
.testFunction('last',
@ -79,19 +92,11 @@ module.exports = {
})
},
'Deploy and use Ballot using external web3': function (browser: NightwatchBrowser) {
'Deploy and use Ballot using external web3 #group2': function (browser: NightwatchBrowser) {
browser
.openFile('Untitled.sol')
.clickLaunchIcon('udapp')
.switchEnvironment('External Http Provider')
.waitForElementPresent('[data-id="basic-http-provider-modal-footer-ok-react"]')
.execute(function () {
const modal = document.querySelector('[data-id="basic-http-provider-modal-footer-ok-react"]') as any
modal.click()
})
.pause(5000)
.waitForElementContainsText('#selectExEnvOptions button', 'External Http Provider')
.connectToExternalHttpProvider('http://localhost:8545', 'Custom')
.clickLaunchIcon('solidity')
.clickLaunchIcon('udapp')
.pause(2000)
@ -105,7 +110,7 @@ module.exports = {
.journalLastChildIncludes('data: 0x5c1...a733c')
},
'Call method from Ballot to check return value using external web3': function (browser: NightwatchBrowser) {
'Call method from Ballot to check return value using external web3 #group2': function (browser: NightwatchBrowser) {
browser
.clickFunction('winnerName - call')
// Test in terminal
@ -118,9 +123,9 @@ module.exports = {
.assert.containsText('*[data-id="treeViewDiv0"]', 'bytes32: winnerName_ 0x48656c6c6f20576f726c64210000000000000000000000000000000000000000')
},
'Compile Ballot using config file': function (browser: NightwatchBrowser) {
'Compile Ballot using config file #group2': function (browser: NightwatchBrowser) {
browser
.addFile('cf.json', {content: configFile})
.addFile('cf.json', { content: configFile })
.clickLaunchIcon('solidity')
.waitForElementVisible('*[data-id="scConfigExpander"]')
.click('*[data-id="scConfigExpander"]')
@ -133,12 +138,12 @@ module.exports = {
.setValue('*[data-id="scConfigFilePathInput"]', 'cf.json')
.sendKeys('*[data-id$="scConfigFilePathInput"]', browser.Keys.ENTER)
.openFile('Untitled.sol')
.verifyContracts(['Ballot'], {wait: 2000, runs: '300'})
.verifyContracts(['Ballot'], { wait: 2000, runs: '300' })
},
'Compile and deploy sample yul file': function (browser: NightwatchBrowser) {
'Compile and deploy sample yul file #group2': function (browser: NightwatchBrowser) {
browser
.addFile('sample.yul', {content: yulSample})
.addFile('sample.yul', { content: yulSample })
.clickLaunchIcon('solidity')
.waitForElementVisible('*[data-id="scConfigExpander"]')
.click('*[data-id="scManualConfiguration"]')

@ -9,13 +9,14 @@ const sources = [
]
module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, null, false)
},
'@sources': function () {
return sources
},
'Compile Ballot with compiler version 0.4.11': function (browser: NightwatchBrowser) {
'Set Ballot 0.4.11': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.clickLaunchIcon('solidity')
@ -23,10 +24,13 @@ module.exports = {
.waitForElementVisible('[for="autoCompile"]')
.click('[for="autoCompile"]')
.verify.elementPresent('[data-id="compilerContainerAutoCompile"]:checked')
},
'Compile Ballot with compiler version 0.4.11 #group1 #group2': function (browser: NightwatchBrowser) {
browser
.testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['Ballot'])
},
'Deploy Ballot': function (browser: NightwatchBrowser) {
'Deploy Ballot #group1': function (browser: NightwatchBrowser) {
browser.pause(500)
.clickLaunchIcon('udapp')
.selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c')
@ -42,7 +46,7 @@ module.exports = {
})
},
'Debug Ballot / delegate': function (browser: NightwatchBrowser) {
'Debug Ballot / delegate #group1': function (browser: NightwatchBrowser) {
browser.pause(500)
.debugTransaction(1)
.pause(2000)
@ -55,16 +59,24 @@ module.exports = {
.checkVariableDebug('callstackpanel', ['0x692a70D2e424a56D2C6C27aA97D1a86395877b3A'])
},
'Access Ballot via at address': function (browser: NightwatchBrowser) {
'Access Ballot via at address #group1': function (browser: NightwatchBrowser) {
browser.clickLaunchIcon('udapp')
.click('*[data-id="universalDappUiUdappClose"]')
.addFile('ballot.abi', { content: ballotABI })
.clickLaunchIcon('udapp')
.click({
selector: '*[data-id="deployAndRunClearInstances"]',
abortOnFailure: false,
suppressNotFoundErrors: true,
})
// we are not changing the visibility for not checksumed contracts
// .addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3B', true, false)
.clickLaunchIcon('filePanel')
.addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3A', true, true)
.pause(500)
.waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]', 60000)
.waitForElementVisible({
locateStrategy: 'xpath',
selector: "//*[@id='instance0x692a70D2e424a56D2C6C27aA97D1a86395877b3A']"
})
.clickInstance(0)
.clickFunction('delegate - transact (not payable)', { types: 'address to', values: '"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db"' })
.testFunction('last',
@ -73,18 +85,11 @@ module.exports = {
'decoded input': { 'address to': '0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB' }
})
},
'Deploy and use Ballot using external web3': function (browser: NightwatchBrowser) {
'Deploy and use Ballot using external web3 #group2': function (browser: NightwatchBrowser) {
browser
.openFile('Untitled.sol')
.clickLaunchIcon('udapp')
.switchEnvironment('External Http Provider')
.waitForElementPresent('[data-id="basic-http-provider-modal-footer-ok-react"]')
.execute(function () {
const modal = document.querySelector('[data-id="basic-http-provider-modal-footer-ok-react"]') as any
modal.click()
})
.clickLaunchIcon('udapp')
.connectToExternalHttpProvider('http://localhost:8545', 'Custom')
.clickLaunchIcon('solidity')
.clickLaunchIcon('udapp')
.pause(2000)
@ -96,7 +101,6 @@ module.exports = {
.clickFunction('delegate - transact (not payable)', { types: 'address to', values: '0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c' })
.journalLastChildIncludes('Ballot.delegate(address)')
.journalLastChildIncludes('data: 0x5c1...a733c')
.end()
}
}

@ -163,7 +163,7 @@ const remixIdeThemes = {
},
flatly: {
primary: '#2C3E50',
secondary: '#95a5a6',
secondary: '#dadfe0',
success: '#18BC9C',
info: '#3498DB',
warning: '#F39C12',
@ -171,7 +171,7 @@ const remixIdeThemes = {
},
spacelab: {
primary: '#446E9B',
secondary: '#999',
secondary: '#dadfe0',
success: '#3CB521',
info: '#3399F3',
warning: '#D47500',
@ -179,7 +179,7 @@ const remixIdeThemes = {
},
cyborg: {
primary: '#2A9FD6',
secondary: '#555',
secondary: '#3c3939',
success: '#77B300',
info: '#93C',
warning: '#F80',

@ -3,6 +3,8 @@ import { NightwatchBrowser } from 'nightwatch'
import { writeFileSync } from 'fs'
import init from '../helpers/init'
import * as hardhatCompilation from '../helpers/hardhat_compilation_8a7ab689ec618720f53ce867a3031c03.json'
import * as foundryCompilation from '../helpers/foundry_compilation.json'
import * as truffle_compilation from '../helpers/truffle_compilation.json'
const assetsTestContract = `import "./contract.sol";
contract Assets {
@ -122,13 +124,57 @@ module.exports = {
writeFileSync('./apps/remix-ide/contracts/artifacts/build-info/c7062fdd360381a85af23eeef31c98f8.json', JSON.stringify(hardhatCompilation))
done()
})
.expect.element('*[data-id="terminalJournal"]').text.to.contain('received compilation result from hardhat').before(60000)
.expect.element('*[data-id="terminalJournal"]').text.to.contain('receiving compilation result from hardhat').before(60000)
browser.clickLaunchIcon('udapp')
.assert.textContains('*[data-id="udappCompiledBy"]', 'Compiled by hardhat')
.selectContract('Lock')
.createContract('1')
.expect.element('*[data-id="terminalJournal"]').text.to.contain('Unlock time should be in the future').before(60000)
},
'Should listen on compilation result from foundry #group6': function (browser: NightwatchBrowser) {
browser.perform((done) => {
console.log('working directory', process.cwd())
writeFileSync('./apps/remix-ide/contracts/out/Counter.sol/Counter.json', JSON.stringify(foundryCompilation))
done()
})
.expect.element('*[data-id="terminalJournal"]').text.to.contain('receiving compilation result from foundry').before(60000)
let contractAaddress
browser.clickLaunchIcon('udapp')
.assert.textContains('*[data-id="udappCompiledBy"]', 'Compiled by foundry')
.selectContract('Counter')
.createContract('')
.getAddressAtPosition(0, (address) => {
console.log(contractAaddress)
contractAaddress = address
})
.clickInstance(0)
.clickFunction('increment - transact (not payable)')
.perform((done) => {
browser.testConstantFunction(contractAaddress, 'number - call', null, '0:\nuint256: 1').perform(() => {
done()
})
})
},
'Should listen on compilation result from truffle #group7': function (browser: NightwatchBrowser) {
browser.perform((done) => {
console.log('working directory', process.cwd())
writeFileSync('./apps/remix-ide/contracts/build/contracts/Migrations.json', JSON.stringify(truffle_compilation))
done()
})
.expect.element('*[data-id="terminalJournal"]').text.to.contain('receiving compilation result from truffle').before(60000)
browser.clickLaunchIcon('udapp')
.assert.textContains('*[data-id="udappCompiledBy"]', 'Compiled by truffle')
.selectContract('Migrations')
.createContract('')
.testFunction('last',
{
status: 'true Transaction mined and execution succeed'
})
}
}

@ -0,0 +1,6 @@
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']
# See more config options https://github.com/foundry-rs/foundry/tree/master/config

@ -0,0 +1,266 @@
{
"abi": [
{
"inputs": [],
"name": "IS_SCRIPT",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "run",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "setUp",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "vm",
"outputs": [
{
"internalType": "contract Vm",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"bytecode": {
"object": "0x60806040526000805460ff1916600117905534801561001d57600080fd5b5061014c8061002d6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80630a9254e4146100515780633a76846314610053578063c04062261461008b578063f8ccbf4714610093575b600080fd5b005b61006e737109709ecfa91a80626ff3989d68f67f5b1dd12d81565b6040516001600160a01b0390911681526020015b60405180910390f35b6100516100b0565b6000546100a09060ff1681565b6040519015158152602001610082565b604080516302bf260160e61b81529051737109709ecfa91a80626ff3989d68f67f5b1dd12d9163afc9804091600480830192600092919082900301818387803b1580156100fc57600080fd5b505af1158015610110573d6000803e3d6000fd5b5050505056fea26469706673582212203a39488c6d5e73072e1dd0c6593caff56e39d0849abc1557f1c6e25cf7dedc2e64736f6c63430008100033",
"sourceMap": "97:126:6:-:0;;;165:28:1;;;-1:-1:-1;;165:28:1;189:4;165:28;;;97:126:6;;;;;;;;;;;;;;;;",
"linkReferences": {}
},
"deployedBytecode": {
"object": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80630a9254e4146100515780633a76846314610053578063c04062261461008b578063f8ccbf4714610093575b600080fd5b005b61006e737109709ecfa91a80626ff3989d68f67f5b1dd12d81565b6040516001600160a01b0390911681526020015b60405180910390f35b6100516100b0565b6000546100a09060ff1681565b6040519015158152602001610082565b604080516302bf260160e61b81529051737109709ecfa91a80626ff3989d68f67f5b1dd12d9163afc9804091600480830192600092919082900301818387803b1580156100fc57600080fd5b505af1158015610110573d6000803e3d6000fd5b5050505056fea26469706673582212203a39488c6d5e73072e1dd0c6593caff56e39d0849abc1557f1c6e25cf7dedc2e64736f6c63430008100033",
"sourceMap": "97:126:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136:26;;316:38:1;;245:64;316:38;;;;;-1:-1:-1;;;;;189:32:9;;;171:51;;159:2;144:18;316:38:1;;;;;;;;168:53:6;;;:::i;165:28:1:-;;;;;;;;;;;;398:14:9;;391:22;373:41;;361:2;346:18;165:28:1;233:187:9;168:53:6;200:14;;;-1:-1:-1;;;200:14:6;;;;245:64:1;;200:12:6;;:14;;;;;269:37:1;;200:14:6;;;;;;;269:37:1;245:64;200:14:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;168:53::o",
"linkReferences": {}
},
"methodIdentifiers": {
"IS_SCRIPT()": "f8ccbf47",
"run()": "c0406226",
"setUp()": "0a9254e4",
"vm()": "3a768463"
},
"ast": {
"absolutePath": "script/Counter.s.sol",
"id": 21582,
"exportedSymbols": {
"CounterScript": [
21581
],
"Script": [
2022
],
"Vm": [
5434
],
"console": [
13498
],
"console2": [
21562
]
},
"nodeType": "SourceUnit",
"src": "39:185:6",
"nodes": [
{
"id": 21564,
"nodeType": "PragmaDirective",
"src": "39:24:6",
"literals": [
"solidity",
"^",
"0.8",
".13"
]
},
{
"id": 21565,
"nodeType": "ImportDirective",
"src": "65:30:6",
"absolutePath": "lib/forge-std/src/Script.sol",
"file": "forge-std/Script.sol",
"nameLocation": "-1:-1:-1",
"scope": 21582,
"sourceUnit": 2023,
"symbolAliases": [],
"unitAlias": ""
},
{
"id": 21581,
"nodeType": "ContractDefinition",
"src": "97:126:6",
"nodes": [
{
"id": 21571,
"nodeType": "FunctionDefinition",
"src": "136:26:6",
"body": {
"id": 21570,
"nodeType": "Block",
"src": "160:2:6",
"statements": []
},
"functionSelector": "0a9254e4",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "setUp",
"nameLocation": "145:5:6",
"parameters": {
"id": 21568,
"nodeType": "ParameterList",
"parameters": [],
"src": "150:2:6"
},
"returnParameters": {
"id": 21569,
"nodeType": "ParameterList",
"parameters": [],
"src": "160:0:6"
},
"scope": 21581,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
},
{
"id": 21580,
"nodeType": "FunctionDefinition",
"src": "168:53:6",
"body": {
"id": 21579,
"nodeType": "Block",
"src": "190:31:6",
"statements": [
{
"expression": {
"arguments": [],
"expression": {
"argumentTypes": [],
"expression": {
"id": 21574,
"name": "vm",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1817,
"src": "200:2:6",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Vm_$5434",
"typeString": "contract Vm"
}
},
"id": 21576,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberLocation": "203:9:6",
"memberName": "broadcast",
"nodeType": "MemberAccess",
"referencedDeclaration": 5173,
"src": "200:12:6",
"typeDescriptions": {
"typeIdentifier": "t_function_external_nonpayable$__$returns$__$",
"typeString": "function () external"
}
},
"id": 21577,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"nameLocations": [],
"names": [],
"nodeType": "FunctionCall",
"src": "200:14:6",
"tryCall": false,
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 21578,
"nodeType": "ExpressionStatement",
"src": "200:14:6"
}
]
},
"functionSelector": "c0406226",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "run",
"nameLocation": "177:3:6",
"parameters": {
"id": 21572,
"nodeType": "ParameterList",
"parameters": [],
"src": "180:2:6"
},
"returnParameters": {
"id": 21573,
"nodeType": "ParameterList",
"parameters": [],
"src": "190:0:6"
},
"scope": 21581,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"abstract": false,
"baseContracts": [
{
"baseName": {
"id": 21566,
"name": "Script",
"nameLocations": [
"123:6:6"
],
"nodeType": "IdentifierPath",
"referencedDeclaration": 2022,
"src": "123:6:6"
},
"id": 21567,
"nodeType": "InheritanceSpecifier",
"src": "123:6:6"
}
],
"canonicalName": "CounterScript",
"contractDependencies": [],
"contractKind": "contract",
"fullyImplemented": true,
"linearizedBaseContracts": [
21581,
2022
],
"name": "CounterScript",
"nameLocation": "106:13:6",
"scope": 21582,
"usedErrors": []
}
],
"license": "UNLICENSED"
},
"id": 6
}

@ -0,0 +1,121 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [
{
"inputs": [],
"name": "IS_SCRIPT",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "run",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "setUp",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "vm",
"outputs": [
{
"internalType": "contract Vm",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"script/Counter.s.sol": "CounterScript"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/src/Script.sol": {
"keccak256": "0x4424dbcb8f5b741475445726f87408fcd89951fad973bec2ca442ee157f910e7",
"license": "MIT",
"urls": [
"bzz-raw://5b0b9f6dfb69245d8f888558ae82bf1d2cdeace46201444fe4b2e6a5283f944a",
"dweb:/ipfs/QmWFSKeFEZngNcwNn7A84EF7pASo5qe6r5oK24r9Kwca7Z"
]
},
"lib/forge-std/src/Vm.sol": {
"keccak256": "0xa0ede8e0d3dc3246912530aed6cacbc4703e4430c4b4acd91963ccea709755ea",
"license": "MIT",
"urls": [
"bzz-raw://a28e7d00aab57ad5159247b0f0f268eda4c6980b29eee7f903578254a2be677f",
"dweb:/ipfs/QmZrM8gY5BpW8o1QckmPNCYbBP5Q7k5DkcHdaVULKVntxp"
]
},
"lib/forge-std/src/console.sol": {
"keccak256": "0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba",
"license": "MIT",
"urls": [
"bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70",
"dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec"
]
},
"lib/forge-std/src/console2.sol": {
"keccak256": "0xbeb823fcdb356244a83aaccdf828ad019ecc1ffaa3dff18e624fc6d5714ea671",
"license": "MIT",
"urls": [
"bzz-raw://4cbe9400340e5f9ec55e2aff3bad1c15fa3afbbe37e80800e6f3fed2ad26854f",
"dweb:/ipfs/QmdJBABsuXkvWxVzEyGXsTE3vyfBPXDdw5xvvtUz3JeoYW"
]
},
"script/Counter.s.sol": {
"keccak256": "0x01edaa1835b1a5bd3f4f66f73451488b8441d30642d3bf1f5fa2c5bf7c005bee",
"license": "UNLICENSED",
"urls": [
"bzz-raw://3c6a0f19216ceeebf4ec16f8f2662a3bebbe18d4037d1399adf2e3e4ccbb57a2",
"dweb:/ipfs/Qmc8NknjPkSgbXLg6zZQ8uKT6kAWBvBXz5JrDvZfa88UNT"
]
}
},
"version": 1
}

@ -0,0 +1,587 @@
{
"abi": [
{
"inputs": [],
"name": "increment",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "number",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newNumber",
"type": "uint256"
}
],
"name": "setNumber",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": {
"object": "0x608060405234801561001057600080fd5b50610125806100206000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146052578063d09de08a14606c575b600080fd5b6050604c3660046095565b6072565b005b605a60005481565b60405190815260200160405180910390f35b60506081565b607b81607b60c3565b60005550565b600080549080608e8360d9565b9190505550565b60006020828403121560a657600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111560d35760d360ad565b92915050565b60006001820160e85760e860ad565b506001019056fea2646970667358221220981d705d73c405a1cadf6bcd0ff9f1d0fcbbc1599040e504e71517ff0d8aa53264736f6c63430008100033",
"sourceMap": "65:198:7:-:0;;;;;;;;;;;;;;;;;;;",
"linkReferences": {}
},
"deployedBytecode": {
"object": "0x6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146052578063d09de08a14606c575b600080fd5b6050604c3660046095565b6072565b005b605a60005481565b60405190815260200160405180910390f35b60506081565b607b81607b60c3565b60005550565b600080549080608e8360d9565b9190505550565b60006020828403121560a657600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111560d35760d360ad565b92915050565b60006001820160e85760e860ad565b506001019056fea2646970667358221220981d705d73c405a1cadf6bcd0ff9f1d0fcbbc1599040e504e71517ff0d8aa53264736f6c63430008100033",
"sourceMap": "65:198:7:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116:86;;;;;;:::i;:::-;;:::i;:::-;;88:21;;;;;;;;;345:25:9;;;333:2;318:18;88:21:7;;;;;;;208:53;;;:::i;116:86::-;180:15;:9;192:3;180:15;:::i;:::-;171:6;:24;-1:-1:-1;116:86:7:o;208:53::-;246:6;:8;;;:6;:8;;;:::i;:::-;;;;;;208:53::o;14:180:9:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:9;;14:180;-1:-1:-1;14:180:9:o;381:127::-;442:10;437:3;433:20;430:1;423:31;473:4;470:1;463:15;497:4;494:1;487:15;513:125;578:9;;;599:10;;;596:36;;;612:18;;:::i;:::-;513:125;;;;:::o;643:135::-;682:3;703:17;;;700:43;;723:18;;:::i;:::-;-1:-1:-1;770:1:9;759:13;;643:135::o",
"linkReferences": {}
},
"methodIdentifiers": {
"increment()": "d09de08a",
"number()": "8381f58a",
"setNumber(uint256)": "3fb5c1cb"
},
"ast": {
"absolutePath": "src/Counter.sol",
"id": 21628,
"exportedSymbols": {
"Counter": [
21605
],
"CounterYann": [
21627
]
},
"nodeType": "SourceUnit",
"src": "39:427:7",
"nodes": [
{
"id": 21583,
"nodeType": "PragmaDirective",
"src": "39:24:7",
"literals": [
"solidity",
"^",
"0.8",
".13"
]
},
{
"id": 21605,
"nodeType": "ContractDefinition",
"src": "65:198:7",
"nodes": [
{
"id": 21585,
"nodeType": "VariableDeclaration",
"src": "88:21:7",
"constant": false,
"functionSelector": "8381f58a",
"mutability": "mutable",
"name": "number",
"nameLocation": "103:6:7",
"scope": 21605,
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 21584,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "88:7:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"visibility": "public"
},
{
"id": 21597,
"nodeType": "FunctionDefinition",
"src": "116:86:7",
"body": {
"id": 21596,
"nodeType": "Block",
"src": "161:41:7",
"statements": [
{
"expression": {
"id": 21594,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"id": 21590,
"name": "number",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21585,
"src": "171:6:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 21593,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"id": 21591,
"name": "newNumber",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21587,
"src": "180:9:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": "+",
"rightExpression": {
"hexValue": "313233",
"id": 21592,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "192:3:7",
"typeDescriptions": {
"typeIdentifier": "t_rational_123_by_1",
"typeString": "int_const 123"
},
"value": "123"
},
"src": "180:15:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "171:24:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 21595,
"nodeType": "ExpressionStatement",
"src": "171:24:7"
}
]
},
"functionSelector": "3fb5c1cb",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "setNumber",
"nameLocation": "125:9:7",
"parameters": {
"id": 21588,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 21587,
"mutability": "mutable",
"name": "newNumber",
"nameLocation": "143:9:7",
"nodeType": "VariableDeclaration",
"scope": 21597,
"src": "135:17:7",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 21586,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "135:7:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"visibility": "internal"
}
],
"src": "134:19:7"
},
"returnParameters": {
"id": 21589,
"nodeType": "ParameterList",
"parameters": [],
"src": "161:0:7"
},
"scope": 21605,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
},
{
"id": 21604,
"nodeType": "FunctionDefinition",
"src": "208:53:7",
"body": {
"id": 21603,
"nodeType": "Block",
"src": "236:25:7",
"statements": [
{
"expression": {
"id": 21601,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"nodeType": "UnaryOperation",
"operator": "++",
"prefix": false,
"src": "246:8:7",
"subExpression": {
"id": 21600,
"name": "number",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21585,
"src": "246:6:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 21602,
"nodeType": "ExpressionStatement",
"src": "246:8:7"
}
]
},
"functionSelector": "d09de08a",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "increment",
"nameLocation": "217:9:7",
"parameters": {
"id": 21598,
"nodeType": "ParameterList",
"parameters": [],
"src": "226:2:7"
},
"returnParameters": {
"id": 21599,
"nodeType": "ParameterList",
"parameters": [],
"src": "236:0:7"
},
"scope": 21605,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"abstract": false,
"baseContracts": [],
"canonicalName": "Counter",
"contractDependencies": [],
"contractKind": "contract",
"fullyImplemented": true,
"linearizedBaseContracts": [
21605
],
"name": "Counter",
"nameLocation": "74:7:7",
"scope": 21628,
"usedErrors": []
},
{
"id": 21627,
"nodeType": "ContractDefinition",
"src": "265:200:7",
"nodes": [
{
"id": 21607,
"nodeType": "VariableDeclaration",
"src": "292:21:7",
"constant": false,
"functionSelector": "8381f58a",
"mutability": "mutable",
"name": "number",
"nameLocation": "307:6:7",
"scope": 21627,
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 21606,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "292:7:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"visibility": "public"
},
{
"id": 21619,
"nodeType": "FunctionDefinition",
"src": "320:84:7",
"body": {
"id": 21618,
"nodeType": "Block",
"src": "365:39:7",
"statements": [
{
"expression": {
"id": 21616,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"id": 21612,
"name": "number",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21607,
"src": "375:6:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 21615,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"id": 21613,
"name": "newNumber",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21609,
"src": "384:9:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": "+",
"rightExpression": {
"hexValue": "39",
"id": 21614,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "396:1:7",
"typeDescriptions": {
"typeIdentifier": "t_rational_9_by_1",
"typeString": "int_const 9"
},
"value": "9"
},
"src": "384:13:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "375:22:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 21617,
"nodeType": "ExpressionStatement",
"src": "375:22:7"
}
]
},
"functionSelector": "3fb5c1cb",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "setNumber",
"nameLocation": "329:9:7",
"parameters": {
"id": 21610,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 21609,
"mutability": "mutable",
"name": "newNumber",
"nameLocation": "347:9:7",
"nodeType": "VariableDeclaration",
"scope": 21619,
"src": "339:17:7",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 21608,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "339:7:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"visibility": "internal"
}
],
"src": "338:19:7"
},
"returnParameters": {
"id": 21611,
"nodeType": "ParameterList",
"parameters": [],
"src": "365:0:7"
},
"scope": 21627,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
},
{
"id": 21626,
"nodeType": "FunctionDefinition",
"src": "410:53:7",
"body": {
"id": 21625,
"nodeType": "Block",
"src": "438:25:7",
"statements": [
{
"expression": {
"id": 21623,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"nodeType": "UnaryOperation",
"operator": "++",
"prefix": false,
"src": "448:8:7",
"subExpression": {
"id": 21622,
"name": "number",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21607,
"src": "448:6:7",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"id": 21624,
"nodeType": "ExpressionStatement",
"src": "448:8:7"
}
]
},
"functionSelector": "d09de08a",
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "increment",
"nameLocation": "419:9:7",
"parameters": {
"id": 21620,
"nodeType": "ParameterList",
"parameters": [],
"src": "428:2:7"
},
"returnParameters": {
"id": 21621,
"nodeType": "ParameterList",
"parameters": [],
"src": "438:0:7"
},
"scope": 21627,
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
}
],
"abstract": false,
"baseContracts": [],
"canonicalName": "CounterYann",
"contractDependencies": [],
"contractKind": "contract",
"fullyImplemented": true,
"linearizedBaseContracts": [
21627
],
"name": "CounterYann",
"nameLocation": "274:11:7",
"scope": 21628,
"usedErrors": []
}
],
"license": "UNLICENSED"
},
"id": 7
}

@ -0,0 +1,82 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [
{
"inputs": [],
"name": "increment",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "number",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newNumber",
"type": "uint256"
}
],
"name": "setNumber",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"src/Counter.sol": "Counter"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"src/Counter.sol": {
"keccak256": "0x74eb20a9c3120b64f0e66b02cf476d5d1ff5e07149a4c52b8e774a6800a40b83",
"license": "UNLICENSED",
"urls": [
"bzz-raw://be4d1233bdd7aaf1846eb4c3b94c58914fa4a4b7a2fa4a5734d9d09c562975dc",
"dweb:/ipfs/QmNVGX1nn75pwmWKQjPdV8cy5u5PHuWGbL6TsztchKqmAZ"
]
}
},
"version": 1
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,561 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "log",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "log_address",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256[]",
"name": "val",
"type": "uint256[]"
}
],
"name": "log_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "int256[]",
"name": "val",
"type": "int256[]"
}
],
"name": "log_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address[]",
"name": "val",
"type": "address[]"
}
],
"name": "log_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "log_bytes",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "log_bytes32",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "int256",
"name": "",
"type": "int256"
}
],
"name": "log_int",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "address",
"name": "val",
"type": "address"
}
],
"name": "log_named_address",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "val",
"type": "uint256[]"
}
],
"name": "log_named_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "int256[]",
"name": "val",
"type": "int256[]"
}
],
"name": "log_named_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "address[]",
"name": "val",
"type": "address[]"
}
],
"name": "log_named_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "bytes",
"name": "val",
"type": "bytes"
}
],
"name": "log_named_bytes",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "val",
"type": "bytes32"
}
],
"name": "log_named_bytes32",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "int256",
"name": "val",
"type": "int256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "decimals",
"type": "uint256"
}
],
"name": "log_named_decimal_int",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "val",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "decimals",
"type": "uint256"
}
],
"name": "log_named_decimal_uint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "int256",
"name": "val",
"type": "int256"
}
],
"name": "log_named_int",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "val",
"type": "string"
}
],
"name": "log_named_string",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "val",
"type": "uint256"
}
],
"name": "log_named_uint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "log_string",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "log_uint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "logs",
"type": "event"
},
{
"inputs": [],
"name": "IS_SCRIPT",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "IS_TEST",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "counter",
"outputs": [
{
"internalType": "contract Counter",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "failed",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "setUp",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "testIncrement",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "x",
"type": "uint256"
}
],
"name": "testSetNumber",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "vm",
"outputs": [
{
"internalType": "contract Vm",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"test/Counter.t.sol": "CounterTest"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/lib/ds-test/src/test.sol": {
"keccak256": "0xb39cd1d5220cb474947b131e15a4538334b7e886af244b440ae5c9c6bba96a54",
"license": "GPL-3.0-or-later",
"urls": [
"bzz-raw://3101520221449ac0070bda3881311a71d9aa87e5210765e875246922cb5cb5f5",
"dweb:/ipfs/Qmbg6kAHNoG7ox9N9Xqd9Ere2H2XixMFWFqvyPwFCzB3Gr"
]
},
"lib/forge-std/src/Script.sol": {
"keccak256": "0x4424dbcb8f5b741475445726f87408fcd89951fad973bec2ca442ee157f910e7",
"license": "MIT",
"urls": [
"bzz-raw://5b0b9f6dfb69245d8f888558ae82bf1d2cdeace46201444fe4b2e6a5283f944a",
"dweb:/ipfs/QmWFSKeFEZngNcwNn7A84EF7pASo5qe6r5oK24r9Kwca7Z"
]
},
"lib/forge-std/src/Test.sol": {
"keccak256": "0x5d84dd1e27d9127431d6f9aaeb681227235f2b0285545384d1dc236cbcab1364",
"license": "MIT",
"urls": [
"bzz-raw://6fe33b19854be51975ae89d4f4d3074a8b4bbd3c0e4dc5befe84d165f7462b55",
"dweb:/ipfs/Qma45Q6fvwpmke2rdPdZapNqjXv17ReoT4xp4Tnj1JdBd7"
]
},
"lib/forge-std/src/Vm.sol": {
"keccak256": "0xa0ede8e0d3dc3246912530aed6cacbc4703e4430c4b4acd91963ccea709755ea",
"license": "MIT",
"urls": [
"bzz-raw://a28e7d00aab57ad5159247b0f0f268eda4c6980b29eee7f903578254a2be677f",
"dweb:/ipfs/QmZrM8gY5BpW8o1QckmPNCYbBP5Q7k5DkcHdaVULKVntxp"
]
},
"lib/forge-std/src/console.sol": {
"keccak256": "0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba",
"license": "MIT",
"urls": [
"bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70",
"dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec"
]
},
"lib/forge-std/src/console2.sol": {
"keccak256": "0xbeb823fcdb356244a83aaccdf828ad019ecc1ffaa3dff18e624fc6d5714ea671",
"license": "MIT",
"urls": [
"bzz-raw://4cbe9400340e5f9ec55e2aff3bad1c15fa3afbbe37e80800e6f3fed2ad26854f",
"dweb:/ipfs/QmdJBABsuXkvWxVzEyGXsTE3vyfBPXDdw5xvvtUz3JeoYW"
]
},
"src/Counter.sol": {
"keccak256": "0x74eb20a9c3120b64f0e66b02cf476d5d1ff5e07149a4c52b8e774a6800a40b83",
"license": "UNLICENSED",
"urls": [
"bzz-raw://be4d1233bdd7aaf1846eb4c3b94c58914fa4a4b7a2fa4a5734d9d09c562975dc",
"dweb:/ipfs/QmNVGX1nn75pwmWKQjPdV8cy5u5PHuWGbL6TsztchKqmAZ"
]
},
"test/Counter.t.sol": {
"keccak256": "0x76bdc40734abcf9acbe5d56422e22662bc218e7d410264f3de6a823036be6a6d",
"license": "UNLICENSED",
"urls": [
"bzz-raw://27118e74e69a15c903cb826430175f337a9ab5cd1bb55a767ae9439e860052bd",
"dweb:/ipfs/QmfNHmcHCDN2eDQpbaDTSRyU4uhcZjpLEdvrudZRLY5knF"
]
}
},
"version": 1
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,99 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [
{
"inputs": [],
"name": "IS_SCRIPT",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "vm",
"outputs": [
{
"internalType": "contract Vm",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"lib/forge-std/src/Script.sol": "Script"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/src/Script.sol": {
"keccak256": "0x4424dbcb8f5b741475445726f87408fcd89951fad973bec2ca442ee157f910e7",
"license": "MIT",
"urls": [
"bzz-raw://5b0b9f6dfb69245d8f888558ae82bf1d2cdeace46201444fe4b2e6a5283f944a",
"dweb:/ipfs/QmWFSKeFEZngNcwNn7A84EF7pASo5qe6r5oK24r9Kwca7Z"
]
},
"lib/forge-std/src/Vm.sol": {
"keccak256": "0xa0ede8e0d3dc3246912530aed6cacbc4703e4430c4b4acd91963ccea709755ea",
"license": "MIT",
"urls": [
"bzz-raw://a28e7d00aab57ad5159247b0f0f268eda4c6980b29eee7f903578254a2be677f",
"dweb:/ipfs/QmZrM8gY5BpW8o1QckmPNCYbBP5Q7k5DkcHdaVULKVntxp"
]
},
"lib/forge-std/src/console.sol": {
"keccak256": "0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba",
"license": "MIT",
"urls": [
"bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70",
"dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec"
]
},
"lib/forge-std/src/console2.sol": {
"keccak256": "0xbeb823fcdb356244a83aaccdf828ad019ecc1ffaa3dff18e624fc6d5714ea671",
"license": "MIT",
"urls": [
"bzz-raw://4cbe9400340e5f9ec55e2aff3bad1c15fa3afbbe37e80800e6f3fed2ad26854f",
"dweb:/ipfs/QmdJBABsuXkvWxVzEyGXsTE3vyfBPXDdw5xvvtUz3JeoYW"
]
}
},
"version": 1
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,505 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "log",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "log_address",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256[]",
"name": "val",
"type": "uint256[]"
}
],
"name": "log_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "int256[]",
"name": "val",
"type": "int256[]"
}
],
"name": "log_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address[]",
"name": "val",
"type": "address[]"
}
],
"name": "log_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "log_bytes",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "log_bytes32",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "int256",
"name": "",
"type": "int256"
}
],
"name": "log_int",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "address",
"name": "val",
"type": "address"
}
],
"name": "log_named_address",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "val",
"type": "uint256[]"
}
],
"name": "log_named_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "int256[]",
"name": "val",
"type": "int256[]"
}
],
"name": "log_named_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "address[]",
"name": "val",
"type": "address[]"
}
],
"name": "log_named_array",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "bytes",
"name": "val",
"type": "bytes"
}
],
"name": "log_named_bytes",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "val",
"type": "bytes32"
}
],
"name": "log_named_bytes32",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "int256",
"name": "val",
"type": "int256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "decimals",
"type": "uint256"
}
],
"name": "log_named_decimal_int",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "val",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "decimals",
"type": "uint256"
}
],
"name": "log_named_decimal_uint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "int256",
"name": "val",
"type": "int256"
}
],
"name": "log_named_int",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "val",
"type": "string"
}
],
"name": "log_named_string",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "val",
"type": "uint256"
}
],
"name": "log_named_uint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "log_string",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "log_uint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "logs",
"type": "event"
},
{
"inputs": [],
"name": "IS_SCRIPT",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "IS_TEST",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "failed",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "vm",
"outputs": [
{
"internalType": "contract Vm",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"lib/forge-std/src/Test.sol": "Test"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/lib/ds-test/src/test.sol": {
"keccak256": "0xb39cd1d5220cb474947b131e15a4538334b7e886af244b440ae5c9c6bba96a54",
"license": "GPL-3.0-or-later",
"urls": [
"bzz-raw://3101520221449ac0070bda3881311a71d9aa87e5210765e875246922cb5cb5f5",
"dweb:/ipfs/Qmbg6kAHNoG7ox9N9Xqd9Ere2H2XixMFWFqvyPwFCzB3Gr"
]
},
"lib/forge-std/src/Script.sol": {
"keccak256": "0x4424dbcb8f5b741475445726f87408fcd89951fad973bec2ca442ee157f910e7",
"license": "MIT",
"urls": [
"bzz-raw://5b0b9f6dfb69245d8f888558ae82bf1d2cdeace46201444fe4b2e6a5283f944a",
"dweb:/ipfs/QmWFSKeFEZngNcwNn7A84EF7pASo5qe6r5oK24r9Kwca7Z"
]
},
"lib/forge-std/src/Test.sol": {
"keccak256": "0x5d84dd1e27d9127431d6f9aaeb681227235f2b0285545384d1dc236cbcab1364",
"license": "MIT",
"urls": [
"bzz-raw://6fe33b19854be51975ae89d4f4d3074a8b4bbd3c0e4dc5befe84d165f7462b55",
"dweb:/ipfs/Qma45Q6fvwpmke2rdPdZapNqjXv17ReoT4xp4Tnj1JdBd7"
]
},
"lib/forge-std/src/Vm.sol": {
"keccak256": "0xa0ede8e0d3dc3246912530aed6cacbc4703e4430c4b4acd91963ccea709755ea",
"license": "MIT",
"urls": [
"bzz-raw://a28e7d00aab57ad5159247b0f0f268eda4c6980b29eee7f903578254a2be677f",
"dweb:/ipfs/QmZrM8gY5BpW8o1QckmPNCYbBP5Q7k5DkcHdaVULKVntxp"
]
},
"lib/forge-std/src/console.sol": {
"keccak256": "0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba",
"license": "MIT",
"urls": [
"bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70",
"dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec"
]
},
"lib/forge-std/src/console2.sol": {
"keccak256": "0xbeb823fcdb356244a83aaccdf828ad019ecc1ffaa3dff18e624fc6d5714ea671",
"license": "MIT",
"urls": [
"bzz-raw://4cbe9400340e5f9ec55e2aff3bad1c15fa3afbbe37e80800e6f3fed2ad26854f",
"dweb:/ipfs/QmdJBABsuXkvWxVzEyGXsTE3vyfBPXDdw5xvvtUz3JeoYW"
]
}
},
"version": 1
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,219 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [
{
"inputs": [],
"name": "arithmeticError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "assertionError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "divisionError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "encodeStorageError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "enumConversionError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "indexOOBError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "lowLevelError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "memOverflowError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "popError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "zeroVarError",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
}
],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"lib/forge-std/src/Test.sol": "stdError"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/lib/ds-test/src/test.sol": {
"keccak256": "0xb39cd1d5220cb474947b131e15a4538334b7e886af244b440ae5c9c6bba96a54",
"license": "GPL-3.0-or-later",
"urls": [
"bzz-raw://3101520221449ac0070bda3881311a71d9aa87e5210765e875246922cb5cb5f5",
"dweb:/ipfs/Qmbg6kAHNoG7ox9N9Xqd9Ere2H2XixMFWFqvyPwFCzB3Gr"
]
},
"lib/forge-std/src/Script.sol": {
"keccak256": "0x4424dbcb8f5b741475445726f87408fcd89951fad973bec2ca442ee157f910e7",
"license": "MIT",
"urls": [
"bzz-raw://5b0b9f6dfb69245d8f888558ae82bf1d2cdeace46201444fe4b2e6a5283f944a",
"dweb:/ipfs/QmWFSKeFEZngNcwNn7A84EF7pASo5qe6r5oK24r9Kwca7Z"
]
},
"lib/forge-std/src/Test.sol": {
"keccak256": "0x5d84dd1e27d9127431d6f9aaeb681227235f2b0285545384d1dc236cbcab1364",
"license": "MIT",
"urls": [
"bzz-raw://6fe33b19854be51975ae89d4f4d3074a8b4bbd3c0e4dc5befe84d165f7462b55",
"dweb:/ipfs/Qma45Q6fvwpmke2rdPdZapNqjXv17ReoT4xp4Tnj1JdBd7"
]
},
"lib/forge-std/src/Vm.sol": {
"keccak256": "0xa0ede8e0d3dc3246912530aed6cacbc4703e4430c4b4acd91963ccea709755ea",
"license": "MIT",
"urls": [
"bzz-raw://a28e7d00aab57ad5159247b0f0f268eda4c6980b29eee7f903578254a2be677f",
"dweb:/ipfs/QmZrM8gY5BpW8o1QckmPNCYbBP5Q7k5DkcHdaVULKVntxp"
]
},
"lib/forge-std/src/console.sol": {
"keccak256": "0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba",
"license": "MIT",
"urls": [
"bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70",
"dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec"
]
},
"lib/forge-std/src/console2.sol": {
"keccak256": "0xbeb823fcdb356244a83aaccdf828ad019ecc1ffaa3dff18e624fc6d5714ea671",
"license": "MIT",
"urls": [
"bzz-raw://4cbe9400340e5f9ec55e2aff3bad1c15fa3afbbe37e80800e6f3fed2ad26854f",
"dweb:/ipfs/QmdJBABsuXkvWxVzEyGXsTE3vyfBPXDdw5xvvtUz3JeoYW"
]
}
},
"version": 1
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,88 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"lib/forge-std/src/Test.sol": "stdMath"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/lib/ds-test/src/test.sol": {
"keccak256": "0xb39cd1d5220cb474947b131e15a4538334b7e886af244b440ae5c9c6bba96a54",
"license": "GPL-3.0-or-later",
"urls": [
"bzz-raw://3101520221449ac0070bda3881311a71d9aa87e5210765e875246922cb5cb5f5",
"dweb:/ipfs/Qmbg6kAHNoG7ox9N9Xqd9Ere2H2XixMFWFqvyPwFCzB3Gr"
]
},
"lib/forge-std/src/Script.sol": {
"keccak256": "0x4424dbcb8f5b741475445726f87408fcd89951fad973bec2ca442ee157f910e7",
"license": "MIT",
"urls": [
"bzz-raw://5b0b9f6dfb69245d8f888558ae82bf1d2cdeace46201444fe4b2e6a5283f944a",
"dweb:/ipfs/QmWFSKeFEZngNcwNn7A84EF7pASo5qe6r5oK24r9Kwca7Z"
]
},
"lib/forge-std/src/Test.sol": {
"keccak256": "0x5d84dd1e27d9127431d6f9aaeb681227235f2b0285545384d1dc236cbcab1364",
"license": "MIT",
"urls": [
"bzz-raw://6fe33b19854be51975ae89d4f4d3074a8b4bbd3c0e4dc5befe84d165f7462b55",
"dweb:/ipfs/Qma45Q6fvwpmke2rdPdZapNqjXv17ReoT4xp4Tnj1JdBd7"
]
},
"lib/forge-std/src/Vm.sol": {
"keccak256": "0xa0ede8e0d3dc3246912530aed6cacbc4703e4430c4b4acd91963ccea709755ea",
"license": "MIT",
"urls": [
"bzz-raw://a28e7d00aab57ad5159247b0f0f268eda4c6980b29eee7f903578254a2be677f",
"dweb:/ipfs/QmZrM8gY5BpW8o1QckmPNCYbBP5Q7k5DkcHdaVULKVntxp"
]
},
"lib/forge-std/src/console.sol": {
"keccak256": "0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba",
"license": "MIT",
"urls": [
"bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70",
"dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec"
]
},
"lib/forge-std/src/console2.sol": {
"keccak256": "0xbeb823fcdb356244a83aaccdf828ad019ecc1ffaa3dff18e624fc6d5714ea671",
"license": "MIT",
"urls": [
"bzz-raw://4cbe9400340e5f9ec55e2aff3bad1c15fa3afbbe37e80800e6f3fed2ad26854f",
"dweb:/ipfs/QmdJBABsuXkvWxVzEyGXsTE3vyfBPXDdw5xvvtUz3JeoYW"
]
}
},
"version": 1
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,163 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "who",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes4",
"name": "fsig",
"type": "bytes4"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "keysHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "slot",
"type": "uint256"
}
],
"name": "SlotFound",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "who",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "slot",
"type": "uint256"
}
],
"name": "WARNING_UninitedSlot",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "b",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "offset",
"type": "uint256"
}
],
"name": "bytesToBytes32",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "pure",
"type": "function"
}
],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"lib/forge-std/src/Test.sol": "stdStorage"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/lib/ds-test/src/test.sol": {
"keccak256": "0xb39cd1d5220cb474947b131e15a4538334b7e886af244b440ae5c9c6bba96a54",
"license": "GPL-3.0-or-later",
"urls": [
"bzz-raw://3101520221449ac0070bda3881311a71d9aa87e5210765e875246922cb5cb5f5",
"dweb:/ipfs/Qmbg6kAHNoG7ox9N9Xqd9Ere2H2XixMFWFqvyPwFCzB3Gr"
]
},
"lib/forge-std/src/Script.sol": {
"keccak256": "0x4424dbcb8f5b741475445726f87408fcd89951fad973bec2ca442ee157f910e7",
"license": "MIT",
"urls": [
"bzz-raw://5b0b9f6dfb69245d8f888558ae82bf1d2cdeace46201444fe4b2e6a5283f944a",
"dweb:/ipfs/QmWFSKeFEZngNcwNn7A84EF7pASo5qe6r5oK24r9Kwca7Z"
]
},
"lib/forge-std/src/Test.sol": {
"keccak256": "0x5d84dd1e27d9127431d6f9aaeb681227235f2b0285545384d1dc236cbcab1364",
"license": "MIT",
"urls": [
"bzz-raw://6fe33b19854be51975ae89d4f4d3074a8b4bbd3c0e4dc5befe84d165f7462b55",
"dweb:/ipfs/Qma45Q6fvwpmke2rdPdZapNqjXv17ReoT4xp4Tnj1JdBd7"
]
},
"lib/forge-std/src/Vm.sol": {
"keccak256": "0xa0ede8e0d3dc3246912530aed6cacbc4703e4430c4b4acd91963ccea709755ea",
"license": "MIT",
"urls": [
"bzz-raw://a28e7d00aab57ad5159247b0f0f268eda4c6980b29eee7f903578254a2be677f",
"dweb:/ipfs/QmZrM8gY5BpW8o1QckmPNCYbBP5Q7k5DkcHdaVULKVntxp"
]
},
"lib/forge-std/src/console.sol": {
"keccak256": "0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba",
"license": "MIT",
"urls": [
"bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70",
"dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec"
]
},
"lib/forge-std/src/console2.sol": {
"keccak256": "0xbeb823fcdb356244a83aaccdf828ad019ecc1ffaa3dff18e624fc6d5714ea671",
"license": "MIT",
"urls": [
"bzz-raw://4cbe9400340e5f9ec55e2aff3bad1c15fa3afbbe37e80800e6f3fed2ad26854f",
"dweb:/ipfs/QmdJBABsuXkvWxVzEyGXsTE3vyfBPXDdw5xvvtUz3JeoYW"
]
}
},
"version": 1
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,48 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"lib/forge-std/src/console.sol": "console"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/src/console.sol": {
"keccak256": "0x91d5413c2434ca58fd278b6e1e79fd98d10c83931cc2596a6038eee4daeb34ba",
"license": "MIT",
"urls": [
"bzz-raw://91ccea707361e48b9b7a161fe81f496b9932bc471e9c4e4e1e9c283f2453cc70",
"dweb:/ipfs/QmcB66sZhQ6Kz7MUHcLE78YXRUZxoZnnxZjN6yATsbB2ec"
]
}
},
"version": 1
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,48 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"lib/forge-std/src/console2.sol": "console2"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/src/console2.sol": {
"keccak256": "0xbeb823fcdb356244a83aaccdf828ad019ecc1ffaa3dff18e624fc6d5714ea671",
"license": "MIT",
"urls": [
"bzz-raw://4cbe9400340e5f9ec55e2aff3bad1c15fa3afbbe37e80800e6f3fed2ad26854f",
"dweb:/ipfs/QmdJBABsuXkvWxVzEyGXsTE3vyfBPXDdw5xvvtUz3JeoYW"
]
}
},
"version": 1
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,343 @@
{
"compiler": {
"version": "0.8.16+commit.07a7930e"
},
"language": "Solidity",
"output": {
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "log",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "log_address",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "log_bytes",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "log_bytes32",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "int256",
"name": "",
"type": "int256"
}
],
"name": "log_int",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "address",
"name": "val",
"type": "address"
}
],
"name": "log_named_address",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "bytes",
"name": "val",
"type": "bytes"
}
],
"name": "log_named_bytes",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "val",
"type": "bytes32"
}
],
"name": "log_named_bytes32",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "int256",
"name": "val",
"type": "int256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "decimals",
"type": "uint256"
}
],
"name": "log_named_decimal_int",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "val",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "decimals",
"type": "uint256"
}
],
"name": "log_named_decimal_uint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "int256",
"name": "val",
"type": "int256"
}
],
"name": "log_named_int",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "val",
"type": "string"
}
],
"name": "log_named_string",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "key",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "val",
"type": "uint256"
}
],
"name": "log_named_uint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "log_string",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "log_uint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "logs",
"type": "event"
},
{
"inputs": [],
"name": "IS_TEST",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "failed",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
],
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
}
},
"settings": {
"compilationTarget": {
"lib/forge-std/lib/ds-test/src/test.sol": "DSTest"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/"
]
},
"sources": {
"lib/forge-std/lib/ds-test/src/test.sol": {
"keccak256": "0xb39cd1d5220cb474947b131e15a4538334b7e886af244b440ae5c9c6bba96a54",
"license": "GPL-3.0-or-later",
"urls": [
"bzz-raw://3101520221449ac0070bda3881311a71d9aa87e5210765e875246922cb5cb5f5",
"dweb:/ipfs/Qmbg6kAHNoG7ox9N9Xqd9Ere2H2XixMFWFqvyPwFCzB3Gr"
]
}
},
"version": 1
}

@ -0,0 +1 @@
// simulate a hardhat project

@ -33,6 +33,7 @@ import { ExternalHttpProvider } from './app/tabs/external-http-provider'
import { Injected0ptimismProvider } from './app/tabs/injected-optimism-provider'
import { InjectedArbitrumOneProvider } from './app/tabs/injected-arbitrum-one-provider'
import { FileDecorator } from './app/plugins/file-decorator'
import { CodeFormat } from './app/plugins/code-format'
const isElectron = require('is-electron')
@ -63,7 +64,7 @@ const Terminal = require('./app/panels/terminal')
const { TabProxy } = require('./app/panels/tab-proxy.js')
class AppComponent {
constructor () {
constructor() {
this.appManager = new RemixAppManager({})
this.queryParams = new QueryParams()
this._components = {}
@ -100,7 +101,7 @@ class AppComponent {
})
}
async run () {
async run() {
// APP_MANAGER
const appManager = this.appManager
const pluginLoader = this.appManager.pluginLoader
@ -161,6 +162,9 @@ class AppComponent {
// ------- FILE DECORATOR PLUGIN ------------------
const fileDecorator = new FileDecorator()
// ------- CODE FORMAT PLUGIN ------------------
const codeFormat = new CodeFormat()
//----- search
const search = new SearchPlugin()
@ -241,6 +245,7 @@ class AppComponent {
offsetToLineColumnConverter,
codeParser,
fileDecorator,
codeFormat,
terminal,
web3Provider,
compileAndRun,
@ -334,6 +339,7 @@ class AppComponent {
filePanel.remixdHandle,
filePanel.gitHandle,
filePanel.hardhatHandle,
filePanel.foundryHandle,
filePanel.truffleHandle,
filePanel.slitherHandle,
linkLibraries,
@ -350,7 +356,7 @@ class AppComponent {
}
}
async activate () {
async activate() {
const queryParams = new QueryParams()
const params = queryParams.get()
@ -367,9 +373,9 @@ class AppComponent {
await this.appManager.activatePlugin(['sidePanel']) // activating host plugin separately
await this.appManager.activatePlugin(['home'])
await this.appManager.activatePlugin(['settings', 'config'])
await this.appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'codeParser', 'fileDecorator', 'terminal', 'blockchain', 'fetchAndCompile', 'contentImport', 'gistHandler'])
await this.appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'codeParser', 'codeFormatter', 'fileDecorator', 'terminal', 'blockchain', 'fetchAndCompile', 'contentImport', 'gistHandler'])
await this.appManager.activatePlugin(['settings'])
await this.appManager.activatePlugin(['walkthrough','storage', 'search','compileAndRun', 'recorder'])
await this.appManager.activatePlugin(['walkthrough', 'storage', 'search', 'compileAndRun', 'recorder'])
this.appManager.on(
'filePanel',

@ -0,0 +1,18 @@
import { WebsocketPlugin } from '@remixproject/engine-web'
import * as packageJson from '../../../../../package.json'
const profile = {
name: 'foundry',
displayName: 'Foundry',
url: 'ws://127.0.0.1:65525',
methods: [],
description: 'Using Remixd daemon, allow to access foundry API',
kind: 'other',
version: packageJson.version
}
export class FoundryHandle extends WebsocketPlugin {
constructor () {
super(profile)
}
}

@ -7,6 +7,7 @@ import Registry from '../state/registry'
import { RemixdHandle } from '../plugins/remixd-handle'
const { GitHandle } = require('../files/git-handle.js')
const { HardhatHandle } = require('../files/hardhat-handle.js')
const { FoundryHandle } = require('../files/foundry-handle.js')
const { TruffleHandle } = require('../files/truffle-handle.js')
const { SlitherHandle } = require('../files/slither-handle.js')
@ -53,6 +54,7 @@ module.exports = class Filepanel extends ViewPlugin {
this.remixdHandle = new RemixdHandle(this.fileProviders.localhost, appManager)
this.gitHandle = new GitHandle()
this.hardhatHandle = new HardhatHandle()
this.foundryHandle = new FoundryHandle()
this.truffleHandle = new TruffleHandle()
this.slitherHandle = new SlitherHandle()
this.workspaces = []

@ -0,0 +1,82 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import prettier from 'prettier/standalone'
import { Options } from 'prettier';
import sol from './code-format/index'
import * as ts from 'prettier/parser-typescript'
import * as babel from 'prettier/parser-babel'
import * as espree from 'prettier/parser-espree'
import path from 'path'
const profile = {
name: 'codeFormatter',
desciption: 'prettier plugin for Remix',
methods: ['format'],
events: [''],
version: '0.0.1'
}
export class CodeFormat extends Plugin {
constructor() {
super(profile)
}
async format(file: string) {
try {
const content = await this.call('fileManager', 'readFile', file)
if (!content) return
let parserName = ''
let options: Options = {
}
switch (path.extname(file)) {
case '.sol':
parserName = 'solidity-parse'
break
case '.ts':
parserName = 'typescript'
options = {
...options,
trailingComma: 'all',
semi: false,
singleQuote: true,
quoteProps: 'as-needed',
bracketSpacing: true,
arrowParens: 'always',
}
break
case '.js':
parserName = "espree"
options = {
...options,
semi: false,
singleQuote: true,
}
break
case '.json':
parserName = 'json'
break
}
const result = prettier.format(content, {
plugins: [sol as any, ts, babel, espree],
parser: parserName,
...options
})
await this.call('fileManager', 'writeFile', file, result)
} catch (e) {
// do nothing
}
}
}
function getRange(index, node) {
if (node.range) {
return node.range[index];
}
if (node.expression && node.expression.range) {
return node.expression.range[index];
}
return null;
}

@ -0,0 +1,61 @@
import { handleComments, printComment } from 'prettier-plugin-solidity/src/comments';
import massageAstNode from 'prettier-plugin-solidity/src/clean.js';
import options from 'prettier-plugin-solidity/src/options.js';
import print from 'prettier-plugin-solidity/src/printer.js';
import loc from 'prettier-plugin-solidity/src/loc.js';
import { parse } from './parser'
// https://prettier.io/docs/en/plugins.html#languages
// https://github.com/ikatyang/linguist-languages/blob/master/data/Solidity.json
const languages = [
{
linguistLanguageId: 237469032,
name: 'Solidity',
type: 'programming',
color: '#AA6746',
aceMode: 'text',
tmScope: 'source.solidity',
extensions: ['.sol'],
parsers: ['solidity-parse'],
vscodeLanguageIds: ['solidity']
}
];
// https://prettier.io/docs/en/plugins.html#parsers
const parser = { astFormat: 'solidity-ast', parse, ...loc };
const parsers = {
'solidity-parse': parser
};
const canAttachComment = (node) =>
node.type && node.type !== 'BlockComment' && node.type !== 'LineComment';
// https://prettier.io/docs/en/plugins.html#printers
const printers = {
'solidity-ast': {
canAttachComment,
handleComments: {
ownLine: handleComments.handleOwnLineComment,
endOfLine: handleComments.handleEndOfLineComment,
remaining: handleComments.handleRemainingComment
},
isBlockComment: handleComments.isBlockComment,
massageAstNode,
print,
printComment
}
};
// https://prettier.io/docs/en/plugins.html#defaultoptions
const defaultOptions = {
bracketSpacing: false,
tabWidth: 4
};
export default {
languages,
parsers,
printers,
options,
defaultOptions
};

@ -0,0 +1,197 @@
// https://prettier.io/docs/en/plugins.html#parsers
import extractComments from 'solidity-comments-extractor';
// use the parser already included in the app
const parser = (window as any).SolidityParser
import semver from 'semver';
const tryHug = (node, operators) => {
if (node.type === 'BinaryOperation' && operators.includes(node.operator))
return {
type: 'TupleExpression',
components: [node],
isArray: false
};
return node;
};
export function parse(text, _parsers, options) {
const compiler = semver.coerce(options.compiler);
const parsed = parser.parse(text, { loc: true, range: true });
parsed.comments = extractComments(text)
parser.visit(parsed, {
PragmaDirective(ctx) {
// if the pragma is not for solidity we leave.
if (ctx.name !== 'solidity') return;
// if the compiler option has not been provided we leave.
if (!compiler) return;
// we make a check against each pragma directive in the document.
if (!semver.satisfies(compiler, ctx.value)) {
// @TODO: investigate the best way to warn that would apply to
// different editors.
// eslint-disable-next-line no-console
console.warn(
`[prettier-solidity] The compiler option is set to '${options.compiler}', which does not satisfy 'pragma solidity ${ctx.value}'.`
);
}
},
ModifierDefinition(ctx) {
if (!ctx.parameters) {
ctx.parameters = [];
}
},
FunctionDefinition(ctx) {
if (!ctx.isConstructor) {
ctx.modifiers.forEach((modifier) => {
if (modifier.arguments && modifier.arguments.length === 0) {
// eslint-disable-next-line no-param-reassign
modifier.arguments = null;
}
});
}
},
ForStatement(ctx) {
if (ctx.initExpression) {
ctx.initExpression.omitSemicolon = true;
}
ctx.loopExpression.omitSemicolon = true;
},
HexLiteral(ctx) {
ctx.value = options.singleQuote
? `hex'${ctx.value.slice(4, -1)}'`
: `hex"${ctx.value.slice(4, -1)}"`;
},
ElementaryTypeName(ctx) {
// if the compiler is below 0.8.0 we will recognize the type 'byte' as an
// alias of 'bytes1'. Otherwise we will ignore this and enforce always
// 'bytes1'.
const pre080 = compiler && semver.satisfies(compiler, '<0.8.0');
if (!pre080 && ctx.name === 'byte') ctx.name = 'bytes1';
if (options.explicitTypes === 'always') {
if (ctx.name === 'uint') ctx.name = 'uint256';
if (ctx.name === 'int') ctx.name = 'int256';
if (pre080 && ctx.name === 'byte') ctx.name = 'bytes1';
} else if (options.explicitTypes === 'never') {
if (ctx.name === 'uint256') ctx.name = 'uint';
if (ctx.name === 'int256') ctx.name = 'int';
if (pre080 && ctx.name === 'bytes1') ctx.name = 'byte';
}
},
BinaryOperation(ctx) {
switch (ctx.operator) {
case '+':
case '-':
ctx.left = tryHug(ctx.left, ['%']);
ctx.right = tryHug(ctx.right, ['%']);
break;
case '*':
ctx.left = tryHug(ctx.left, ['/', '%']);
break;
case '/':
ctx.left = tryHug(ctx.left, ['*', '%']);
break;
case '%':
ctx.left = tryHug(ctx.left, ['*', '/', '%']);
break;
case '**':
// If the compiler has not been given as an option using we leave a**b**c.
if (!compiler) break;
if (semver.satisfies(compiler, '<0.8.0')) {
// If the compiler is less than 0.8.0 then a**b**c is formatted as
// (a**b)**c.
ctx.left = tryHug(ctx.left, ['**']);
break;
}
if (
ctx.left.type === 'BinaryOperation' &&
ctx.left.operator === '**'
) {
// the parser still organizes the a**b**c as (a**b)**c so we need
// to restructure it.
ctx.right = {
type: 'TupleExpression',
components: [
{
type: 'BinaryOperation',
operator: '**',
left: ctx.left.right,
right: ctx.right
}
],
isArray: false
};
ctx.left = ctx.left.left;
}
break;
case '<<':
case '>>':
ctx.left = tryHug(ctx.left, ['+', '-', '*', '/', '**', '<<', '>>']);
ctx.right = tryHug(ctx.right, ['+', '-', '*', '/', '**']);
break;
case '&':
ctx.left = tryHug(ctx.left, ['+', '-', '*', '/', '**', '<<', '>>']);
ctx.right = tryHug(ctx.right, ['+', '-', '*', '/', '**', '<<', '>>']);
break;
case '|':
ctx.left = tryHug(ctx.left, [
'+',
'-',
'*',
'/',
'**',
'<<',
'>>',
'&',
'^'
]);
ctx.right = tryHug(ctx.right, [
'+',
'-',
'*',
'/',
'**',
'<<',
'>>',
'&',
'^'
]);
break;
case '^':
ctx.left = tryHug(ctx.left, [
'+',
'-',
'*',
'/',
'**',
'<<',
'>>',
'&'
]);
ctx.right = tryHug(ctx.right, [
'+',
'-',
'*',
'/',
'**',
'<<',
'>>',
'&'
]);
break;
case '||':
ctx.left = tryHug(ctx.left, ['&&']);
ctx.right = tryHug(ctx.right, ['&&']);
break;
case '&&':
default:
break;
}
}
});
return parsed;
}

@ -6,6 +6,7 @@ import { CompilationResult } from '@remix-project/remix-solidity'
import CodeParserGasService from './services/code-parser-gas-service'
import CodeParserCompiler from './services/code-parser-compiler'
import CodeParserAntlrService from './services/code-parser-antlr-service'
import CodeParserImports, { CodeParserImportsData } from './services/code-parser-imports'
import React from 'react'
import { Profile } from '@remixproject/plugin-utils'
import { ContractDefinitionAstNode, EventDefinitionAstNode, FunctionCallAstNode, FunctionDefinitionAstNode, IdentifierAstNode, ImportDirectiveAstNode, ModifierDefinitionAstNode, SourceUnitAstNode, StructDefinitionAstNode, VariableDeclarationAstNode } from 'dist/libs/remix-analyzer/src/types'
@ -15,7 +16,7 @@ import { ParseResult } from './types/antlr-types'
const profile: Profile = {
name: 'codeParser',
methods: ['nodesAtPosition', 'getContractNodes', 'getCurrentFileNodes', 'getLineColumnOfNode', 'getLineColumnOfPosition', 'getFunctionParamaters', 'getDeclaration', 'getFunctionReturnParameters', 'getVariableDeclaration', 'getNodeDocumentation', 'getNodeLink', 'listAstNodes', 'getANTLRBlockAtPosition', 'getLastNodeInLine', 'resolveImports', 'parseSolidity', 'getNodesWithScope', 'getNodesWithName', 'getNodes', 'compile', 'getNodeById', 'getLastCompilationResult', 'positionOfDefinition', 'definitionAtPosition', 'jumpToDefinition', 'referrencesAtPosition', 'referencesOf', 'getActiveHighlights', 'gasEstimation', 'declarationOf', 'getGasEstimates'],
methods: ['nodesAtPosition', 'getContractNodes', 'getCurrentFileNodes', 'getLineColumnOfNode', 'getLineColumnOfPosition', 'getFunctionParamaters', 'getDeclaration', 'getFunctionReturnParameters', 'getVariableDeclaration', 'getNodeDocumentation', 'getNodeLink', 'listAstNodes', 'getANTLRBlockAtPosition', 'getLastNodeInLine', 'resolveImports', 'parseSolidity', 'getNodesWithScope', 'getNodesWithName', 'getNodes', 'compile', 'getNodeById', 'getLastCompilationResult', 'positionOfDefinition', 'definitionAtPosition', 'jumpToDefinition', 'referrencesAtPosition', 'referencesOf', 'getActiveHighlights', 'gasEstimation', 'declarationOf', 'getGasEstimates', 'getImports'],
events: [],
version: '0.0.1'
}
@ -70,12 +71,15 @@ export class CodeParser extends Plugin {
gasService: CodeParserGasService
compilerService: CodeParserCompiler
antlrService: CodeParserAntlrService
importService: CodeParserImports
parseSolidity: (text: string) => Promise<antlr.ParseResult>
getLastNodeInLine: (ast: string) => Promise<any>
listAstNodes: () => Promise<any>
getANTLRBlockAtPosition: (position: any, text?: string) => Promise<any>
getCurrentFileAST: (text?: string) => Promise<ParseResult>
getImports: () => Promise<CodeParserImportsData[]>
constructor(astWalker: any) {
super(profile)
@ -94,7 +98,7 @@ export class CodeParser extends Plugin {
}
const showGasSettings = await this.call('config', 'getAppParameter', 'show-gas')
const showErrorSettings = await this.call('config', 'getAppParameter', 'display-errors')
if(showGasSettings || showErrorSettings || completionSettings) {
if (showGasSettings || showErrorSettings || completionSettings) {
await this.compilerService.compile()
}
}
@ -104,13 +108,14 @@ export class CodeParser extends Plugin {
this.gasService = new CodeParserGasService(this)
this.compilerService = new CodeParserCompiler(this)
this.antlrService = new CodeParserAntlrService(this)
this.importService = new CodeParserImports(this)
this.parseSolidity = this.antlrService.parseSolidity.bind(this.antlrService)
this.getLastNodeInLine = this.antlrService.getLastNodeInLine.bind(this.antlrService)
this.listAstNodes = this.antlrService.listAstNodes.bind(this.antlrService)
this.getANTLRBlockAtPosition = this.antlrService.getANTLRBlockAtPosition.bind(this.antlrService)
this.getCurrentFileAST = this.antlrService.getCurrentFileAST.bind(this.antlrService)
this.getImports = this.importService.getImports.bind(this.importService)
this.on('editor', 'didChangeFile', async (file) => {
await this.call('editor', 'discardLineTexts')
@ -119,9 +124,18 @@ export class CodeParser extends Plugin {
this.on('filePanel', 'setWorkspace', async () => {
await this.call('fileDecorator', 'clearFileDecorators')
await this.importService.setFileTree()
})
this.on('fileManager', 'fileAdded', async () => {
await this.importService.setFileTree()
})
this.on('fileManager', 'fileRemoved', async () => {
await this.importService.setFileTree()
})
this.on('fileManager', 'currentFileChanged', async () => {
await this.call('editor', 'discardLineTexts')
await this.handleChangeEvents()
@ -135,8 +149,6 @@ export class CodeParser extends Plugin {
}
/**
*
* @returns
@ -145,10 +157,6 @@ export class CodeParser extends Plugin {
return this.compilerAbstract
}
getSubNodes<T extends genericASTNode>(node: T): number[] {
return node.nodeType == "ContractDefinition" && node.contractDependencies;
}

@ -8,6 +8,7 @@ import { fileDecoration, fileDecorationType } from '@remix-ui/file-decorators'
import { sourceMappingDecoder } from '@remix-project/remix-debug'
import { CompilerRetriggerMode } from '@remix-project/remix-solidity-ts';
import { MarkerSeverity } from 'monaco-editor';
import { findLinesInStringWithMatch, SearchResultLine } from '@remix-ui/search'
type errorMarker = {
message: string
@ -23,7 +24,7 @@ type errorMarker = {
}
},
file: string
}
}
export default class CodeParserCompiler {
plugin: CodeParser
compiler: any // used to compile the current file seperately from the main compiler
@ -43,36 +44,47 @@ export default class CodeParserCompiler {
this.errorState = true
const result = new CompilerAbstract('soljson', data, source, input)
let allErrors: errorMarker[] = []
if (data.errors) {
const sources = result.getSourceCode().sources
if (data.errors || data.error) {
const file = await this.plugin.call('fileManager', 'getCurrentFile')
const currentFileContent = await this.plugin.call('fileManager', 'readFile', file)
const sources = result.getSourceCode().sources || []
if (data.error) {
if (data.error.formattedMessage) {
// mark this file as error
const errorMarker = await this.createErrorMarker(data.error, file, { start: { line: 0, column: 0 }, end: { line: 0, column: 100 } })
allErrors = [...allErrors, errorMarker]
}
} else {
for (const error of data.errors) {
if (!error.sourceLocation) {
// mark this file as error
const errorMarker = await this.createErrorMarker(error, file, { start: { line: 0, column: 0 }, end: { line: 0, column: 100 } })
allErrors = [...allErrors, errorMarker]
} else {
const lineBreaks = sourceMappingDecoder.getLinebreakPositions(sources[error.sourceLocation.file].content)
const lineColumn = sourceMappingDecoder.convertOffsetToLineColumn({
start: error.sourceLocation.start,
length: error.sourceLocation.end - error.sourceLocation.start
}, lineBreaks)
const filePath = error.sourceLocation.file
const fileTarget = await this.plugin.call('fileManager', 'getUrlFromPath', filePath)
allErrors = [...allErrors, {
message: error.formattedMessage,
severity: error.severity === 'error' ? MarkerSeverity.Error : MarkerSeverity.Warning,
position: {
start: {
line: ((lineColumn.start && lineColumn.start.line) || 0) + 1,
column: ((lineColumn.start && lineColumn.start.column) || 0) + 1
},
end: {
line: ((lineColumn.end && lineColumn.end.line) || 0) + 1,
column: ((lineColumn.end && lineColumn.end.column) || 0) + 1
const importFilePositions = await this.getPositionForImportErrors(fileTarget.file, currentFileContent)
for (const importFilePosition of importFilePositions) {
for (const line of importFilePosition.lines) {
allErrors = [...allErrors, await this.createErrorMarker(error, file, line.position)]
}
}
, file: filePath
}]
allErrors = [...allErrors, await this.createErrorMarker(error, filePath, lineColumn)]
}
}
}
const displayErrors = await this.plugin.call('config', 'getAppParameter', 'display-errors')
if(displayErrors) await this.plugin.call('editor', 'addErrorMarker', allErrors)
if (displayErrors) await this.plugin.call('editor', 'addErrorMarker', allErrors)
this.addDecorators(allErrors, sources)
} else {
await this.plugin.call('editor', 'clearErrorMarkers', result.getSourceCode().sources)
@ -131,7 +143,7 @@ export default class CodeParserCompiler {
"*": ["evm.gasEstimates"]
}
},
"evmVersion": state.evmVersion && state.evmVersion.toString() || "byzantium",
"evmVersion": state.evmVersion && state.evmVersion.toString() || "berlin",
}
}
@ -149,8 +161,8 @@ export default class CodeParserCompiler {
async addDecorators(allErrors: errorMarker[], sources: any) {
const displayErrors = await this.plugin.call('config', 'getAppParameter', 'display-errors')
if(!displayErrors) return
const errorsPerFiles: {[fileName: string]: errorMarker[]} = {}
if (!displayErrors) return
const errorsPerFiles: { [fileName: string]: errorMarker[] } = {}
for (const error of allErrors) {
if (!errorsPerFiles[error.file]) {
errorsPerFiles[error.file] = []
@ -164,7 +176,7 @@ export default class CodeParserCompiler {
}
// sort errorPerFiles by error priority
const sortedErrorsPerFiles: {[fileName: string]: errorMarker[]} = {}
const sortedErrorsPerFiles: { [fileName: string]: errorMarker[] } = {}
for (const fileName in errorsPerFiles) {
const errors = errorsPerFiles[fileName]
errors.sort((a, b) => {
@ -178,10 +190,11 @@ export default class CodeParserCompiler {
const decorators: fileDecoration[] = []
for (const fileName in sortedErrorsPerFiles) {
const errors = sortedErrorsPerFiles[fileName]
const fileTarget = await this.plugin.call('fileManager', 'getPathFromUrl', fileName)
const decorator: fileDecoration = {
path: fileName,
path: fileTarget.file,
isDirectory: false,
fileStateType: errors[0].severity == MarkerSeverity.Error? fileDecorationType.Error : fileDecorationType.Warning,
fileStateType: errors[0].severity == MarkerSeverity.Error ? fileDecorationType.Error : fileDecorationType.Warning,
fileStateLabelClass: errors[0].severity == MarkerSeverity.Error ? 'text-danger' : 'text-warning',
fileStateIconClass: '',
fileStateIcon: '',
@ -193,8 +206,9 @@ export default class CodeParserCompiler {
decorators.push(decorator)
}
for (const fileName of filesWithOutErrors) {
const fileTarget = await this.plugin.call('fileManager', 'getPathFromUrl', fileName)
const decorator: fileDecoration = {
path: fileName,
path: fileTarget.file,
isDirectory: false,
fileStateType: fileDecorationType.None,
fileStateLabelClass: '',
@ -211,8 +225,27 @@ export default class CodeParserCompiler {
}
async createErrorMarker(error: any, filePath: string, lineColumn): Promise<errorMarker> {
return {
message: error.formattedMessage,
severity: error.severity === 'error' ? MarkerSeverity.Error : MarkerSeverity.Warning,
position: {
start: {
line: ((lineColumn.start && lineColumn.start.line) || 0) + 1,
column: ((lineColumn.start && lineColumn.start.column) || 0) + 1
},
end: {
line: ((lineColumn.end && lineColumn.end.line) || 0) + 1,
column: ((lineColumn.end && lineColumn.end.column) || 0) + 1
}
}
, file: filePath
}
}
async clearDecorators(sources: any) {
const decorators: fileDecoration[] = []
if (!sources) return
for (const fileName of Object.keys(sources)) {
const decorator: fileDecoration = {
path: fileName,
@ -232,4 +265,13 @@ export default class CodeParserCompiler {
await this.plugin.call('fileDecorator', 'setFileDecorators', decorators)
}
async getPositionForImportErrors(importedFileName: string, text: string) {
const re = new RegExp(importedFileName, 'gi')
const result: SearchResultLine[] = findLinesInStringWithMatch(
text,
re
)
return result
}
}

@ -0,0 +1,82 @@
'use strict'
import { CodeParser } from "../code-parser";
export type CodeParserImportsData= {
files?: string[],
modules?: string[],
packages?: string[],
}
export default class CodeParserImports {
plugin: CodeParser
data: CodeParserImportsData = {}
constructor(plugin: CodeParser) {
this.plugin = plugin
this.init()
}
async getImports(){
return this.data
}
async init() {
// @ts-ignore
const txt = await import('raw-loader!libs/remix-ui/editor/src/lib/providers/completion/contracts/contracts.txt')
this.data.modules = txt.default.split('\n')
.filter(x => x !== '')
.map(x => x.replace('./node_modules/', ''))
.filter(x => {
if(x.includes('@openzeppelin')) {
return !x.includes('mock')
}else{
return true
}
})
// get unique first words of the values in the array
this.data.packages = [...new Set(this.data.modules.map(x => x.split('/')[0]))]
}
setFileTree = async () => {
this.data.files = await this.getDirectory('/')
this.data.files = this.data.files.filter(x => x.endsWith('.sol') && !x.startsWith('.deps') && !x.startsWith('.git'))
}
getDirectory = async (dir: string) => {
let result = []
const files = await this.plugin.call('fileManager', 'readdir', dir)
const fileArray = this.normalize(files)
for (const fi of fileArray) {
if (fi) {
const type = fi.data.isDirectory
if (type === true) {
result = [...result, ...(await this.getDirectory(`${fi.filename}`))]
} else {
result = [...result, fi.filename]
}
}
}
return result
}
normalize = filesList => {
const folders = []
const files = []
Object.keys(filesList || {}).forEach(key => {
if (filesList[key].isDirectory) {
folders.push({
filename: key,
data: filesList[key]
})
} else {
files.push({
filename: key,
data: filesList[key]
})
}
})
return [...folders, ...files]
}
}

@ -46,6 +46,7 @@ export class RemixdHandle extends WebsocketPlugin {
if (this.appManager.isActive('hardhat')) this.appManager.deactivatePlugin('hardhat')
if (this.appManager.isActive('truffle')) this.appManager.deactivatePlugin('truffle')
if (this.appManager.isActive('slither')) this.appManager.deactivatePlugin('slither')
if (this.appManager.isActive('foundry')) this.appManager.deactivatePlugin('foundry')
this.localhostProvider.close((error) => {
if (error) console.log(error)
})
@ -94,6 +95,7 @@ export class RemixdHandle extends WebsocketPlugin {
this.call('manager', 'activatePlugin', 'hardhat')
this.call('manager', 'activatePlugin', 'truffle')
this.call('manager', 'activatePlugin', 'slither')
this.call('manager', 'activatePlugin', 'foundry')
}
}
if (this.localhostProvider.isConnected()) {

@ -25,7 +25,7 @@
--gray:#555;
--gray-dark:#222;
--primary:#2a9fd6;
--secondary:#555;
--secondary:#3c3939;
--success:#77b300;
--info:#93c;
--warning:#f80;
@ -5595,7 +5595,7 @@ a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:
background-color:#2180ac!important
}
.bg-secondary {
background-color:#555!important
background-color:#3c3939!important
}
a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover {
background-color:#3c3c3c!important
@ -8358,7 +8358,7 @@ a.text-warning:focus,a.text-warning:hover {
color:#b35f00!important
}
.text-danger {
color:#c00!important
color:#ff4242!important
}
a.text-danger:focus,a.text-danger:hover {
color:maroon!important
@ -8594,7 +8594,7 @@ legend {
color:#555
}
.nav-pills .nav-link.active,.nav-tabs .nav-link.active {
background-color:#2a9fd6
background-color:#034767
}
.breadcrumb a {
color:#fff

@ -24,7 +24,7 @@
--gray:#95a5a6;
--gray-dark:#343a40;
--primary:#2c3e50;
--secondary:#95a5a6;
--secondary:#dadfe0;
--success:#18bc9c;
--info:#3498db;
--warning:#f39c12;
@ -4460,7 +4460,7 @@ a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:
background-color:#1a252f!important
}
.bg-secondary {
background-color:#95a5a6!important
background-color:#dadfe0!important
}
a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover {
background-color:#798d8f!important

@ -25,7 +25,7 @@
--gray:#777;
--gray-dark:#333;
--primary:#446e9b;
--secondary:#999;
--secondary:#dadfe0;
--success:#3cb521;
--info:#3399f3;
--warning:#d47500;
@ -5596,7 +5596,7 @@ a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:
background-color:#345578!important
}
.bg-secondary {
background-color:#999!important
background-color:#dadfe0!important
}
a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover {
background-color:gray!important

@ -3641,7 +3641,7 @@ input[type="submit"].btn-block {
.nav-tabs .nav-item.show .nav-link,
.nav-tabs .nav-link.active {
color: #fff;
background-color: var(--body-bg);
background-color: #2a2c3f;
border-color: #3f4455;
}
.nav-tabs .dropdown-menu {

@ -11,7 +11,7 @@ const requiredModules = [ // services + layout views + system views
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout',
'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy',
'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected-optimism-provider', 'injected-arbitrum-one-provider',
'compileAndRun', 'search', 'recorder', 'fileDecorator', 'codeParser']
'compileAndRun', 'search', 'recorder', 'fileDecorator', 'codeParser', 'codeFormatter']
// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)
const dependentModules = ['hardhat', 'truffle', 'slither']

@ -63,6 +63,16 @@ export class CompilerArtefacts extends Plugin {
this.compilersArtefacts.__last = new CompilerAbstract(languageVersion, data, source)
saveCompilationPerFileResult(file, source, languageVersion, data)
})
this.on('truffle', 'compilationFinished', (file, source, languageVersion, data) => {
this.compilersArtefacts.__last = new CompilerAbstract(languageVersion, data, source)
saveCompilationPerFileResult(file, source, languageVersion, data)
})
this.on('foundry', 'compilationFinished', (file, source, languageVersion, data) => {
this.compilersArtefacts.__last = new CompilerAbstract(languageVersion, data, source)
saveCompilationPerFileResult(file, source, languageVersion, data)
})
}
/**

@ -1,5 +1,12 @@
import { IRange } from "monaco-editor";
import monaco from "../../../types/monaco";
import path from "path";
type CodeParserImportsData = {
files?: string[],
modules?: string[],
packages?: string[],
}
export function getStringCompletionItems(range: IRange, monaco): monaco.languages.CompletionItem[] {
return [
@ -176,13 +183,6 @@ export function getCompletionSnippets(range: IRange, monaco): monaco.languages.C
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
range
},
{
label: 'import',
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: 'import "${1:library}";',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
range
},
{
label: 'SPDX-License-Identifier',
kind: monaco.languages.CompletionItemKind.Snippet,
@ -330,7 +330,7 @@ function CreateCompletionItem(label: string, kind: monaco.languages.CompletionIt
export function GetCompletionKeywords(range: IRange, monaco): monaco.languages.CompletionItem[] {
const completionItems = [];
const keywords = ['modifier', 'mapping', 'break', 'continue', 'delete', 'else', 'for',
'after', 'promise', 'alias', 'apply','auto', 'copyof', 'default', 'define', 'final', 'implements',
'after', 'promise', 'alias', 'apply', 'auto', 'copyof', 'default', 'define', 'final', 'implements',
'inline', 'let', 'macro', 'match', 'mutable', 'null', 'of', 'partial', 'reference', 'relocatable',
'sealed', 'sizeof', 'static', 'supports', 'switch', 'typedef',
'if', 'new', 'return', 'returns', 'while', 'using', 'emit', 'anonymous', 'indexed',
@ -390,6 +390,89 @@ export function GeCompletionUnits(range: IRange, monaco): monaco.languages.Compl
return completionItems;
}
export function GetImports(range: IRange
, monaco, data: CodeParserImportsData
, word: string
): monaco.languages.CompletionItem[] {
let list = []
if (!word.startsWith('@')) {
word = word.replace('"', '');
const nextPaths = [...new Set(data.files
.filter((item) => item.startsWith(word))
.map((item) => item.replace(word, '').split('/')[0]))]
list = [...list, ...nextPaths
.filter((item) => !item.endsWith('.sol'))
.map((item) => {
return {
kind: monaco.languages.CompletionItemKind.Folder,
range: range,
label: `${item}`,
insertText: `${item}`,
}
})]
list = [...list,
...data.files
.filter((item) => item.startsWith(word))
.map((item) => {
return {
kind: monaco.languages.CompletionItemKind.File,
range: range,
label: `${item}`,
insertText: `${item.replace(word, '')}`,
}
})]
}
if (word === '@' || word === '') {
list = [...list, ...data.packages.map((item) => {
return {
kind: monaco.languages.CompletionItemKind.Module,
range: range,
label: `${item}`,
insertText: word === '@' ? `${item.replace('@', '')}` : `${item}`,
}
})]
}
if (word.startsWith('@') && word.length > 1) {
const nextPaths = [...new Set(data.modules
.filter((item) => item.startsWith(word))
.map((item) => item.replace(word, '').split('/')[0]))]
list = [...list, ...nextPaths
.filter((item) => !item.endsWith('.sol'))
.map((item) => {
return {
kind: monaco.languages.CompletionItemKind.Folder,
range: range,
label: `${item}`,
insertText: `${item}`,
}
})]
list = [...list
, ...data.modules
.filter((item) => item.startsWith(word))
.map((item) => {
// remove the first part if it starts with @
let label = item;
if (label.startsWith('@')) {
label = label.substring(label.indexOf('/') + 1);
}
const filename = path.basename(label)
return {
kind: monaco.languages.CompletionItemKind.Reference,
range: range,
label: `${filename}: ${label}`,
insertText: `${item.replace(word, '')}`,
}
})
]
}
return list;
};
export function GetGlobalVariable(range: IRange, monaco): monaco.languages.CompletionItem[] {
return [
{

@ -0,0 +1,198 @@
./node_modules/@openzeppelin/contracts/access/AccessControl.sol
./node_modules/@openzeppelin/contracts/access/AccessControlCrossChain.sol
./node_modules/@openzeppelin/contracts/access/AccessControlEnumerable.sol
./node_modules/@openzeppelin/contracts/access/IAccessControl.sol
./node_modules/@openzeppelin/contracts/access/IAccessControlEnumerable.sol
./node_modules/@openzeppelin/contracts/access/Ownable.sol
./node_modules/@openzeppelin/contracts/crosschain/amb/CrossChainEnabledAMB.sol
./node_modules/@openzeppelin/contracts/crosschain/amb/LibAMB.sol
./node_modules/@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol
./node_modules/@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol
./node_modules/@openzeppelin/contracts/crosschain/arbitrum/LibArbitrumL1.sol
./node_modules/@openzeppelin/contracts/crosschain/arbitrum/LibArbitrumL2.sol
./node_modules/@openzeppelin/contracts/crosschain/CrossChainEnabled.sol
./node_modules/@openzeppelin/contracts/crosschain/errors.sol
./node_modules/@openzeppelin/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol
./node_modules/@openzeppelin/contracts/crosschain/optimism/LibOptimism.sol
./node_modules/@openzeppelin/contracts/crosschain/polygon/CrossChainEnabledPolygonChild.sol
./node_modules/@openzeppelin/contracts/finance/PaymentSplitter.sol
./node_modules/@openzeppelin/contracts/finance/VestingWallet.sol
./node_modules/@openzeppelin/contracts/governance/compatibility/GovernorCompatibilityBravo.sol
./node_modules/@openzeppelin/contracts/governance/compatibility/IGovernorCompatibilityBravo.sol
./node_modules/@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol
./node_modules/@openzeppelin/contracts/governance/extensions/GovernorPreventLateQuorum.sol
./node_modules/@openzeppelin/contracts/governance/extensions/GovernorProposalThreshold.sol
./node_modules/@openzeppelin/contracts/governance/extensions/GovernorSettings.sol
./node_modules/@openzeppelin/contracts/governance/extensions/GovernorTimelockCompound.sol
./node_modules/@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol
./node_modules/@openzeppelin/contracts/governance/extensions/GovernorVotes.sol
./node_modules/@openzeppelin/contracts/governance/extensions/GovernorVotesComp.sol
./node_modules/@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol
./node_modules/@openzeppelin/contracts/governance/extensions/IGovernorTimelock.sol
./node_modules/@openzeppelin/contracts/governance/Governor.sol
./node_modules/@openzeppelin/contracts/governance/IGovernor.sol
./node_modules/@openzeppelin/contracts/governance/TimelockController.sol
./node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol
./node_modules/@openzeppelin/contracts/governance/utils/Votes.sol
./node_modules/@openzeppelin/contracts/interfaces/draft-IERC1822.sol
./node_modules/@openzeppelin/contracts/interfaces/draft-IERC2612.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC1155.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC1155MetadataURI.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC1155Receiver.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC1271.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC1363Receiver.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC1363Spender.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC165.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC1820Implementer.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC1820Registry.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC20.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC20Metadata.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC2981.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC3156.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC4626.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC721.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC721Enumerable.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC721Metadata.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC721Receiver.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC777.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC777Recipient.sol
./node_modules/@openzeppelin/contracts/interfaces/IERC777Sender.sol
./node_modules/@openzeppelin/contracts/metatx/ERC2771Context.sol
./node_modules/@openzeppelin/contracts/metatx/MinimalForwarder.sol
./node_modules/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol
./node_modules/@openzeppelin/contracts/proxy/beacon/IBeacon.sol
./node_modules/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol
./node_modules/@openzeppelin/contracts/proxy/Clones.sol
./node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol
./node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol
./node_modules/@openzeppelin/contracts/proxy/Proxy.sol
./node_modules/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol
./node_modules/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol
./node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol
./node_modules/@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol
./node_modules/@openzeppelin/contracts/security/Pausable.sol
./node_modules/@openzeppelin/contracts/security/PullPayment.sol
./node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol
./node_modules/@openzeppelin/contracts/token/common/ERC2981.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/ERC1155.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Pausable.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/IERC1155.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol
./node_modules/@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol
./node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20FlashMint.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Snapshot.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20VotesComp.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC20Wrapper.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol
./node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
./node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol
./node_modules/@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol
./node_modules/@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol
./node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
./node_modules/@openzeppelin/contracts/token/ERC20/utils/TokenTimelock.sol
./node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol
./node_modules/@openzeppelin/contracts/token/ERC721/extensions/draft-ERC721Votes.sol
./node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol
./node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol
./node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol
./node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721Royalty.sol
./node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol
./node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol
./node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol
./node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol
./node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
./node_modules/@openzeppelin/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol
./node_modules/@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol
./node_modules/@openzeppelin/contracts/token/ERC777/ERC777.sol
./node_modules/@openzeppelin/contracts/token/ERC777/IERC777.sol
./node_modules/@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol
./node_modules/@openzeppelin/contracts/token/ERC777/IERC777Sender.sol
./node_modules/@openzeppelin/contracts/token/ERC777/presets/ERC777PresetFixedSupply.sol
./node_modules/@openzeppelin/contracts/utils/Address.sol
./node_modules/@openzeppelin/contracts/utils/Arrays.sol
./node_modules/@openzeppelin/contracts/utils/Base64.sol
./node_modules/@openzeppelin/contracts/utils/Checkpoints.sol
./node_modules/@openzeppelin/contracts/utils/Context.sol
./node_modules/@openzeppelin/contracts/utils/Counters.sol
./node_modules/@openzeppelin/contracts/utils/Create2.sol
./node_modules/@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol
./node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol
./node_modules/@openzeppelin/contracts/utils/cryptography/MerkleProof.sol
./node_modules/@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol
./node_modules/@openzeppelin/contracts/utils/escrow/ConditionalEscrow.sol
./node_modules/@openzeppelin/contracts/utils/escrow/Escrow.sol
./node_modules/@openzeppelin/contracts/utils/escrow/RefundEscrow.sol
./node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol
./node_modules/@openzeppelin/contracts/utils/introspection/ERC165Checker.sol
./node_modules/@openzeppelin/contracts/utils/introspection/ERC165Storage.sol
./node_modules/@openzeppelin/contracts/utils/introspection/ERC1820Implementer.sol
./node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol
./node_modules/@openzeppelin/contracts/utils/introspection/IERC1820Implementer.sol
./node_modules/@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol
./node_modules/@openzeppelin/contracts/utils/math/Math.sol
./node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol
./node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol
./node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol
./node_modules/@openzeppelin/contracts/utils/math/SignedSafeMath.sol
./node_modules/@openzeppelin/contracts/utils/Multicall.sol
./node_modules/@openzeppelin/contracts/utils/StorageSlot.sol
./node_modules/@openzeppelin/contracts/utils/Strings.sol
./node_modules/@openzeppelin/contracts/utils/structs/BitMaps.sol
./node_modules/@openzeppelin/contracts/utils/structs/DoubleEndedQueue.sol
./node_modules/@openzeppelin/contracts/utils/structs/EnumerableMap.sol
./node_modules/@openzeppelin/contracts/utils/structs/EnumerableSet.sol
./node_modules/@openzeppelin/contracts/utils/Timers.sol
./node_modules/@openzeppelin/contracts/vendor/amb/IAMB.sol
./node_modules/@openzeppelin/contracts/vendor/arbitrum/IArbSys.sol
./node_modules/@openzeppelin/contracts/vendor/arbitrum/IBridge.sol
./node_modules/@openzeppelin/contracts/vendor/arbitrum/IInbox.sol
./node_modules/@openzeppelin/contracts/vendor/arbitrum/IMessageProvider.sol
./node_modules/@openzeppelin/contracts/vendor/arbitrum/IOutbox.sol
./node_modules/@openzeppelin/contracts/vendor/compound/ICompoundTimelock.sol
./node_modules/@openzeppelin/contracts/vendor/optimism/ICrossDomainMessenger.sol
./node_modules/@openzeppelin/contracts/vendor/polygon/IFxMessageProcessor.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3FlashCallback.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3MintCallback.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/IUniswapV3PoolDeployer.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolEvents.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolOwnerActions.sol
./node_modules/@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol
./node_modules/@uniswap/v3-core/contracts/libraries/BitMath.sol
./node_modules/@uniswap/v3-core/contracts/libraries/FixedPoint128.sol
./node_modules/@uniswap/v3-core/contracts/libraries/FixedPoint96.sol
./node_modules/@uniswap/v3-core/contracts/libraries/FullMath.sol
./node_modules/@uniswap/v3-core/contracts/libraries/LiquidityMath.sol
./node_modules/@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol
./node_modules/@uniswap/v3-core/contracts/libraries/Oracle.sol
./node_modules/@uniswap/v3-core/contracts/libraries/Position.sol
./node_modules/@uniswap/v3-core/contracts/libraries/SafeCast.sol
./node_modules/@uniswap/v3-core/contracts/libraries/SqrtPriceMath.sol
./node_modules/@uniswap/v3-core/contracts/libraries/SwapMath.sol
./node_modules/@uniswap/v3-core/contracts/libraries/Tick.sol
./node_modules/@uniswap/v3-core/contracts/libraries/TickBitmap.sol
./node_modules/@uniswap/v3-core/contracts/libraries/TickMath.sol
./node_modules/@uniswap/v3-core/contracts/libraries/TransferHelper.sol
./node_modules/@uniswap/v3-core/contracts/libraries/UnsafeMath.sol

@ -4,7 +4,7 @@ import { isArray } from "lodash"
import { editor, languages, Position } from "monaco-editor"
import monaco from "../../types/monaco"
import { EditorUIProps } from "../remix-ui-editor"
import { GeCompletionUnits, GetCompletionKeywords, getCompletionSnippets, GetCompletionTypes, getContextualAutoCompleteBTypeName, getContextualAutoCompleteByGlobalVariable, GetGlobalFunctions, GetGlobalVariable } from "./completion/completionGlobals"
import { GeCompletionUnits, GetCompletionKeywords, getCompletionSnippets, GetCompletionTypes, getContextualAutoCompleteBTypeName, getContextualAutoCompleteByGlobalVariable, GetGlobalFunctions, GetGlobalVariable, GetImports } from "./completion/completionGlobals"
export class RemixCompletionProvider implements languages.CompletionItemProvider {
@ -16,11 +16,11 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
this.monaco = monaco
}
triggerCharacters = ['.', '']
triggerCharacters = ['.', '', '"', '@', '/']
async provideCompletionItems(model: editor.ITextModel, position: Position, context: monaco.languages.CompletionContext): Promise<monaco.languages.CompletionList | undefined> {
const completionSettings = await this.props.plugin.call('config', 'getAppParameter', 'settings/auto-completion')
if(!completionSettings) return
if (!completionSettings) return
const word = model.getWordUntilPosition(position);
const range = {
startLineNumber: position.lineNumber,
@ -33,6 +33,28 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
let nodes: AstNode[] = []
let suggestions: monaco.languages.CompletionItem[] = []
if (context.triggerCharacter === '"' || context.triggerCharacter === '@' || context.triggerCharacter === '/') {
const lastpart = line.substring(0, position.column - 1).split(';').pop()
if (lastpart.startsWith('import')) {
const imports = await this.props.plugin.call('codeParser', 'getImports')
if (context.triggerCharacter === '"' || context.triggerCharacter === '@') {
suggestions = [...suggestions,
...GetImports(range, this.monaco, imports, context.triggerCharacter),
]
} else if (context.triggerCharacter === '/') {
const word = line.split('"')[1]
suggestions = [...suggestions,
...GetImports(range, this.monaco, imports, word),
]
} else {
return
}
}
} else
if (context.triggerCharacter === '.') {
const lineTextBeforeCursor: string = line.substring(0, position.column - 1)
const lastNodeInExpression = await this.getLastNodeInExpression(lineTextBeforeCursor)
@ -41,7 +63,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
let dotCompleted = false
// handles completion from for builtin types
if(lastNodeInExpression.memberName === 'sender') { // exception for this member
if (lastNodeInExpression.memberName === 'sender') { // exception for this member
lastNodeInExpression.name = 'sender'
}
const globalCompletion = getContextualAutoCompleteByGlobalVariable(lastNodeInExpression.name, range, this.monaco)
@ -244,7 +266,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
const contractNodes = fileNodes.contracts[node.name].contractNodes
for (const contractNode of Object.values(contractNodes)) {
if (contractNode['name'] === ANTLRBlock.name
|| (contractNode['kind'] === 'constructor' && ANTLRBlock.name === null )
|| (contractNode['kind'] === 'constructor' && ANTLRBlock.name === null)
) {
let nodeOfScope = await this.props.plugin.call('codeParser', 'getNodesWithScope', (contractNode as any).id)
nodes = [...nodes, ...nodeOfScope]
@ -279,7 +301,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
return true
}
}
if(node.outSideBlock){ return true }
if (node.outSideBlock) { return true }
return false
})
@ -387,9 +409,9 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
nodes = [...nodes, ...filterNodes(nodeOfScope.members, nodeOfScope)]
} else if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ArrayTypeName') {
suggestions = [...suggestions, ...getContextualAutoCompleteBTypeName('ArrayTypeName', range, this.monaco)]
} else if(nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ElementaryTypeName' && nodeOfScope.typeName.name === 'bytes') {
} else if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ElementaryTypeName' && nodeOfScope.typeName.name === 'bytes') {
suggestions = [...suggestions, ...getContextualAutoCompleteBTypeName('bytes', range, this.monaco)]
} else if(nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ElementaryTypeName' && nodeOfScope.typeName.name === 'address') {
} else if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ElementaryTypeName' && nodeOfScope.typeName.name === 'address') {
suggestions = [...suggestions, ...getContextualAutoCompleteBTypeName('address', range, this.monaco)]
}
}

@ -13,8 +13,22 @@ export class RemixDefinitionProvider implements monaco.languages.DefinitionProvi
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async provideDefinition(model: monaco.editor.ITextModel, position: monaco.Position, token: monaco.CancellationToken): Promise<monaco.languages.Definition | monaco.languages.LocationLink[]> {
const cursorPosition = this.props.editorAPI.getCursorPosition()
const jumpLocation = await this.jumpToDefinition(cursorPosition)
let jumpLocation = await this.jumpToDefinition(cursorPosition)
if (!jumpLocation || !jumpLocation.fileName) {
const line = model.getLineContent(position.lineNumber)
const lastpart = line.substring(0, position.column - 1).split(';').pop()
if (lastpart.startsWith('import')) {
const importPath = line.substring(lastpart.indexOf('"') + 1)
const importPath2 = importPath.substring(0, importPath.indexOf('"'))
jumpLocation = {
startLineNumber: 1,
startColumn: 1,
endColumn: 1,
endLineNumber: 1,
fileName: importPath2
}
}
}
return [{
uri: this.monaco.Uri.parse(jumpLocation.fileName),
range: {

@ -122,9 +122,11 @@ export const EditorUI = (props: EditorUIProps) => {
\t\t\t\t\t\t\t|_| \\_\\ |_____| |_| |_| |___| /_/\\_\\ |___| |____/ |_____|\n\n
\t\t\t\t\t\t\tKeyboard Shortcuts:\n
\t\t\t\t\t\t\t\tCTRL + S: Compile the current contract\n
\t\t\t\t\t\t\t\tCtrl + Shift + F : Open the File Explorer\n
\t\t\t\t\t\t\t\tCtrl + Shift + A : Open the Plugin Manager\n
\t\t\t\t\t\t\t\tCTRL + SHIFT + S: Compile the current contract & Run an associated script\n\n
\t\t\t\t\t\t\t\tCTRL + Shift + F : Open the File Explorer\n
\t\t\t\t\t\t\t\tCTRL + Shift + A : Open the Plugin Manager\n
\t\t\t\t\t\t\t\tCTRL + SHIFT + S: Compile the current contract & Run an associated script\n
\t\t\t\t\t\t\tEditor Keyboard Shortcuts:\n
\t\t\t\t\t\t\t\tCTRL + Alt + F : Format the code in the current file\n
\t\t\t\t\t\t\tImportant Links:\n
\t\t\t\t\t\t\t\tOfficial website about the Remix Project: https://remix-project.org/\n
\t\t\t\t\t\t\t\tOfficial documentation: https://remix-ide.readthedocs.io/en/latest/\n
@ -156,6 +158,7 @@ export const EditorUI = (props: EditorUIProps) => {
const infoColor = formatColor('--info')
const darkColor = formatColor('--dark')
const secondaryColor = formatColor('--secondary')
const primaryColor = formatColor('--primary')
const textColor = formatColor('--text') || darkColor
const textbackground = formatColor('--text-background') || lightColor
@ -264,7 +267,8 @@ export const EditorUI = (props: EditorUIProps) => {
'editorSuggestWidget.background': lightColor,
'editorSuggestWidget.selectedBackground': secondaryColor,
'editorSuggestWidget.selectedForeground': textColor,
'editorSuggestWidget.highlightForeground': infoColor,
'editorSuggestWidget.highlightForeground': primaryColor,
'editorSuggestWidget.focusHighlightForeground': infoColor,
'editor.lineHighlightBorder': secondaryColor,
'editor.lineHighlightBackground': textbackground === darkColor ? lightColor : secondaryColor,
'editorGutter.background': lightColor,
@ -568,6 +572,21 @@ export const EditorUI = (props: EditorUIProps) => {
],
run: () => { editor.updateOptions({ fontSize: editor.getOption(43).fontSize - 1 }) },
}
const formatAction = {
id: "autoFormat",
label: "Format Code",
contextMenuOrder: 0, // choose the order
contextMenuGroupId: "formatting", // create a new grouping
keybindings: [
// eslint-disable-next-line no-bitwise
monacoRef.current.KeyMod.Shift | monacoRef.current.KeyMod.Alt | monacoRef.current.KeyCode.KeyF,
],
run: async () => {
const file = await props.plugin.call('fileManager', 'getCurrentFile')
await props.plugin.call('codeFormatter', 'format', file)
},
}
editor.addAction(formatAction)
editor.addAction(zoomOutAction)
editor.addAction(zoominAction)
const editorService = editor._codeEditorService;

@ -15,7 +15,7 @@ export function RemixPluginPanel (props: RemixPanelProps) {
<>
{props.header}
<div className="pluginsContainer">
<div className='plugins pb-2' id='plugins'>
<div className='plugins' id='plugins'>
{Object.values(props.plugins).map((pluginRecord) => {
return <RemixUIPanelPlugin key={pluginRecord.profile.name} pluginRecord={pluginRecord} />
})}

@ -52,7 +52,7 @@ const PermissionHandlerDialog = (props: PermissionHandlerProps) => {
<h6>{to.displayName} :</h6>
<p> {to.description || <i>No description Provided</i>}</p>
{pluginMessage()}
{ sensitiveCall ? <p className='text-warning'><i className="fas fa-exclamation-triangle mr-2" aria-hidden="true"></i>You are going to process a sensitive call. Please make sure you trust this plugin.</p> : '' }
{ sensitiveCall ? <p className='text-warning'><i className="fas fa-exclamation-triangle mr-2" aria-hidden="true"></i>Make sure you trust this plugin before processing this call.</p> : '' }
</article>
<article className='remember'>
{ !sensitiveCall && <div className='form-check'>

@ -53,6 +53,10 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
plugin.on('hardhat', 'compilationFinished', (file, source, languageVersion, data) => broadcastCompilationResult('hardhat', plugin, dispatch, file, source, languageVersion, data))
plugin.on('foundry', 'compilationFinished', (file, source, languageVersion, data) => broadcastCompilationResult('foundry', plugin, dispatch, file, source, languageVersion, data))
plugin.on('truffle', 'compilationFinished', (file, source, languageVersion, data) => broadcastCompilationResult('truffle', plugin, dispatch, file, source, languageVersion, data))
plugin.on('udapp', 'setEnvironmentModeReducer', (env: { context: string, fork: string }, from: string) => {
plugin.call('notification', 'toast', envChangeNotification(env, from))
setExecutionContext(plugin, dispatch, env)

@ -1 +1,3 @@
export { SearchTab } from './lib/components/Search';
export * from './lib/components/results/SearchHelper';
export * from './lib/types';

@ -80,9 +80,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
const tmp: RegExpExecArray | null = /^(\d+.\d+.\d+)/.exec(version)
return tmp ? tmp[1] : version
}
if (version != '' && !semver.gt(truncateVersion(version), '0.4.12')) {
if (version && version != '' && !semver.gt(truncateVersion(version), '0.4.12')) {
setIsSupportedVersion(false)
setRunButtonTitle('Sselect Solidity compiler version greater than 0.4.12.')
setRunButtonTitle('Select Solidity compiler version greater than 0.4.12.')
} else {
setIsSupportedVersion(true)
setRunButtonTitle('Run static analysis')

@ -186,7 +186,7 @@ export const TabsUI = (props: TabsUIProps) => {
}}
>
<TabList className="d-flex flex-row align-items-center">
{props.tabs.map((tab, i) => <Tab className="py-1" key={tab.name}>{renderTab(tab, i)}</Tab>)}
{props.tabs.map((tab, i) => <Tab className="" key={tab.name}>{renderTab(tab, i)}</Tab>)}
</TabList>
{props.tabs.map((tab) => <TabPanel key={tab.name} ></TabPanel>)}
</Tabs>

@ -7,7 +7,7 @@
}
.remixui_fileexplorer {
position : relative;
overflow-y : auto;
overflow-y : hidden;
}
.remixui_fileExplorerTree {
cursor : default;

@ -27,7 +27,8 @@ const services = {
hardhat: (readOnly: boolean) => new servicesList.HardhatClient(readOnly),
truffle: (readOnly: boolean) => new servicesList.TruffleClient(readOnly),
slither: (readOnly: boolean) => new servicesList.SlitherClient(readOnly),
folder: (readOnly: boolean) => new servicesList.Sharedfolder(readOnly)
folder: (readOnly: boolean) => new servicesList.Sharedfolder(readOnly),
foundry: (readOnly: boolean) => new servicesList.FoundryClient(readOnly)
}
// Similar object is also defined in websocket.ts
@ -36,11 +37,12 @@ const ports = {
hardhat: 65522,
slither: 65523,
truffle: 65524,
foundry: 65525,
folder: 65520
}
const killCallBack: Array<any> = [] // any is function
function startService<S extends 'git' | 'hardhat' | 'truffle' | 'slither' | 'folder'> (service: S, callback: (ws: WS, sharedFolderClient: servicesList.Sharedfolder, error?:Error) => void) {
function startService<S extends 'git' | 'hardhat' | 'truffle' | 'slither' | 'folder' | 'foundry'> (service: S, callback: (ws: WS, sharedFolderClient: servicesList.Sharedfolder, error?:Error) => void) {
const socket = new WebSocket(ports[service], { remixIdeUrl: program.remixIde }, () => services[service](program.readOnly || false))
socket.start(callback)
killCallBack.push(socket.close.bind(socket))
@ -134,6 +136,19 @@ function errorHandler (error: any, service: string) {
sharedFolderClient.sharedFolder(program.sharedFolder)
})
}
// Run foundry service if a founndry project is shared as folder
const foundryConfigFilePath = absolutePath('./', program.sharedFolder)
const isFoundryProject = existsSync(foundryConfigFilePath + '/foundry.toml')
if (isFoundryProject) {
startService('foundry', (ws: WS, sharedFolderClient: servicesList.Sharedfolder, error: Error) => {
if (error) {
errorHandler(error, 'foundry')
return false
}
sharedFolderClient.setWebSocket(ws)
sharedFolderClient.sharedFolder(program.sharedFolder)
})
}
/*
startService('git', (ws: WS, sharedFolderClient: servicesList.Sharedfolder) => {
sharedFolderClient.setWebSocket(ws)

@ -3,3 +3,4 @@ export { GitClient } from './services/gitClient'
export { HardhatClient } from './services/hardhatClient'
export { TruffleClient } from './services/truffleClient'
export { SlitherClient } from './services/slitherClient'
export { FoundryClient } from './services/foundryClient'

@ -0,0 +1,138 @@
import * as WS from 'ws' // eslint-disable-line
import { PluginClient } from '@remixproject/plugin'
import * as chokidar from 'chokidar'
import * as utils from '../utils'
import * as fs from 'fs-extra'
import { basename, join } from 'path'
const { spawn } = require('child_process') // eslint-disable-line
export class FoundryClient extends PluginClient {
methods: Array<string>
websocket: WS
currentSharedFolder: string
watcher: chokidar.FSWatcher
warnlog: boolean
constructor (private readOnly = false) {
super()
this.methods = ['compile']
}
setWebSocket (websocket: WS): void {
this.websocket = websocket
this.websocket.addEventListener('close', () => {
this.warnlog = false
if (this.watcher) this.watcher.close()
})
}
sharedFolder (currentSharedFolder: string): void {
this.currentSharedFolder = currentSharedFolder
this.listenOnFoundryCompilation()
}
compile (configPath: string) {
return new Promise((resolve, reject) => {
if (this.readOnly) {
const errMsg = '[Hardhat Compilation]: Cannot compile in read-only mode'
return reject(new Error(errMsg))
}
const cmd = `forge build`
const options = { cwd: this.currentSharedFolder, shell: true }
const child = spawn(cmd, options)
let result = ''
let error = ''
child.stdout.on('data', (data) => {
const msg = `[Foundry Compilation]: ${data.toString()}`
console.log('\x1b[32m%s\x1b[0m', msg)
result += msg + '\n'
})
child.stderr.on('data', (err) => {
error += `[Foundry Compilation]: ${err.toString()} \n`
})
child.on('close', () => {
if (error && result) resolve(error + result)
else if (error) reject(error)
else resolve(result)
})
})
}
listenOnFoundryCompilation () {
try {
const buildPath = utils.absolutePath('out', this.currentSharedFolder)
this.watcher = chokidar.watch(buildPath, { depth: 3, ignorePermissionErrors: true, ignoreInitial: true })
const compilationResult = {
input: {},
output: {
contracts: {},
sources: {}
},
solcVersion: null
}
const processArtifact = async () => {
const folderFiles = await fs.readdir(buildPath)
// name of folders are file names
for (const file of folderFiles) {
await this.readContract(join(buildPath, file), compilationResult)
}
if (!this.warnlog) {
// @ts-ignore
this.call('terminal', 'log', 'receiving compilation result from foundry')
this.warnlog = true
}
this.emit('compilationFinished', '', { sources: compilationResult.input } , 'soljson', compilationResult.output, compilationResult.solcVersion)
}
this.watcher.on('change', async (f: string) => processArtifact())
this.watcher.on('add', async (f: string) => processArtifact())
} catch (e) {
console.log(e)
}
}
async readContract (contractFolder, compilationResultPart) {
const files = await fs.readdir(contractFolder)
for (const file of files) {
const content = await fs.readFile(join(contractFolder, file), { encoding: 'utf-8' })
await this.feedContractArtifactFile(file, content, compilationResultPart)
}
}
async feedContractArtifactFile (path, content, compilationResultPart) {
const contentJSON = JSON.parse(content)
if (path.endsWith('.metadata.json')) {
// extract source and version
compilationResultPart.solcVersion = contentJSON.compiler.version
for (const path in contentJSON.sources) {
const absPath = utils.absolutePath(path, this.currentSharedFolder)
try {
const content = await fs.readFile(absPath, { encoding: 'utf-8' })
compilationResultPart.input[path] = { content }
} catch (e) {
compilationResultPart.input[path] = { content: '' }
}
}
} else {
const contractName = basename(path).replace('.json', '')
// extract data
if (!compilationResultPart.output['sources'][contentJSON.ast.absolutePath]) compilationResultPart.output['sources'][contentJSON.ast.absolutePath] = {}
compilationResultPart.output['sources'][contentJSON.ast.absolutePath] = {
ast: contentJSON['ast'],
id: contentJSON['id']
}
if (!compilationResultPart.output['contracts'][contentJSON.ast.absolutePath]) compilationResultPart.output['contracts'][contentJSON.ast.absolutePath] = {}
// delete contentJSON['ast']
contentJSON.bytecode.object = contentJSON.bytecode.object.replace('0x', '')
contentJSON.deployedBytecode.object = contentJSON.deployedBytecode.object.replace('0x', '')
compilationResultPart.output['contracts'][contentJSON.ast.absolutePath][contractName] = {
abi: contentJSON.abi,
evm: {
bytecode: contentJSON.bytecode,
deployedBytecode: contentJSON.deployedBytecode,
methodIdentifiers: contentJSON.methodIdentifiers
}
}
}
}
}

@ -10,6 +10,7 @@ export class HardhatClient extends PluginClient {
websocket: WS
currentSharedFolder: string
watcher: chokidar.FSWatcher
warnlog: boolean
constructor (private readOnly = false) {
super()
@ -19,6 +20,7 @@ export class HardhatClient extends PluginClient {
setWebSocket (websocket: WS): void {
this.websocket = websocket
this.websocket.addEventListener('close', () => {
this.warnlog = false
if (this.watcher) this.watcher.close()
})
}
@ -58,14 +60,19 @@ export class HardhatClient extends PluginClient {
listenOnHardhatCompilation () {
try {
const buildPath = utils.absolutePath('artifacts/build-info', this.currentSharedFolder)
this.watcher = chokidar.watch(buildPath, { depth: 0, ignorePermissionErrors: true })
this.watcher = chokidar.watch(buildPath, { depth: 0, ignorePermissionErrors: true, ignoreInitial: true })
const processArtifact = async (path: string) => {
if (path.endsWith('.json')) {
const content = await fs.readFile(path, { encoding: 'utf-8' })
const compilationResult = JSON.parse(content)
if (!this.warnlog) {
// @ts-ignore
this.call('terminal', 'log', 'received compilation result from hardhat')
this.emit('compilationFinished', '', compilationResult.input, 'soljson', compilationResult.output, compilationResult.solcVersion)
this.call('terminal', 'log', 'receiving compilation result from hardhat')
this.warnlog = true
}
this.emit('compilationFinished', '', { sources: compilationResult.input.sources }, 'soljson', compilationResult.output, compilationResult.solcVersion)
}
}
this.watcher.on('change', (path: string) => processArtifact(path))

@ -1,11 +1,17 @@
import * as WS from 'ws' // eslint-disable-line
import { PluginClient } from '@remixproject/plugin'
import * as chokidar from 'chokidar'
import * as utils from '../utils'
import * as fs from 'fs-extra'
import { basename, join } from 'path'
const { spawn } = require('child_process') // eslint-disable-line
export class TruffleClient extends PluginClient {
methods: Array<string>
websocket: WS
currentSharedFolder: string
watcher: chokidar.FSWatcher
warnLog: boolean
constructor (private readOnly = false) {
super()
@ -14,10 +20,15 @@ export class TruffleClient extends PluginClient {
setWebSocket (websocket: WS): void {
this.websocket = websocket
this.websocket.addEventListener('close', () => {
this.warnLog = false
if (this.watcher) this.watcher.close()
})
}
sharedFolder (currentSharedFolder: string): void {
this.currentSharedFolder = currentSharedFolder
this.listenOnTruffleCompilation()
}
compile (configPath: string) {
@ -46,4 +57,74 @@ export class TruffleClient extends PluginClient {
})
})
}
listenOnTruffleCompilation () {
try {
const buildPath = utils.absolutePath('build/contracts', this.currentSharedFolder)
this.watcher = chokidar.watch(buildPath, { depth: 3, ignorePermissionErrors: true, ignoreInitial: true })
const compilationResult = {
input: {},
output: {
contracts: {},
sources: {}
},
solcVersion: null
}
const processArtifact = async () => {
const folderFiles = await fs.readdir(buildPath)
// name of folders are file names
for (const file of folderFiles) {
if (file.endsWith('.json')) {
const content = await fs.readFile(join(buildPath, file), { encoding: 'utf-8' })
await this.feedContractArtifactFile(file, content, compilationResult)
}
}
if (!this.warnLog) {
// @ts-ignore
this.call('terminal', 'log', 'receiving compilation result from truffle')
this.warnLog = true
}
this.emit('compilationFinished', '', { sources: compilationResult.input }, 'soljson', compilationResult.output, compilationResult.solcVersion)
}
this.watcher.on('change', async (f: string) => processArtifact())
this.watcher.on('add', async (f: string) => processArtifact())
} catch (e) {
console.log(e)
}
}
async feedContractArtifactFile (path, content, compilationResultPart) {
const contentJSON = JSON.parse(content)
const contractName = basename(path).replace('.json', '')
compilationResultPart.solcVersion = contentJSON.compiler.version
compilationResultPart.input[path] = { content: contentJSON.source }
// extract data
const relPath = utils.relativePath(contentJSON.ast.absolutePath, this.currentSharedFolder)
if (!compilationResultPart.output['sources'][relPath]) compilationResultPart.output['sources'][relPath] = {}
const location = contentJSON.ast.src.split(':')
const id = parseInt(location[location.length - 1])
compilationResultPart.output['sources'][relPath] = {
ast: contentJSON.ast,
id
}
if (!compilationResultPart.output['contracts'][relPath]) compilationResultPart.output['contracts'][relPath] = {}
// delete contentJSON['ast']
compilationResultPart.output['contracts'][relPath][contractName] = {
abi: contentJSON.abi,
evm: {
bytecode: {
object: contentJSON.bytecode.replace('0x', ''),
sourceMap: contentJSON.sourceMap,
linkReferences: contentJSON.linkReferences
},
deployedBytecode: {
object: contentJSON.deployedBytecode.replace('0x', ''),
sourceMap: contentJSON.deployedSourceMap,
linkReferences: contentJSON.deployedLinkReferences
}
}
}
}
}

@ -21,7 +21,8 @@ export default class WebSocket {
65521: 'git',
65522: 'hardhat',
65523: 'slither',
65524: 'truffle'
65524: 'truffle',
65525: 'foundry'
}
this.server.on('error', (error: Error) => {

@ -108,7 +108,8 @@
"test-browser": "npm-run-all -lpr selenium make-mock-compiler serve browsertest",
"watch": "watchify apps/remix-ide/src/index.js -dv -p browserify-reload -o apps/remix-ide/build/app.js --exclude solc",
"reinstall": "rm ./node-modules/ -rf && rm yarn.lock && rm ./build/ -rf && yarn install & yarn run build",
"ganache-cli": "npx ganache-cli"
"ganache-cli": "npx ganache-cli",
"build-contracts": "find ./node_modules/@openzeppelin/contracts | grep -i '.sol' > libs/remix-ui/editor/src/lib/providers/completion/contracts/contracts.txt && find ./node_modules/@uniswap/v3-core/contracts | grep -i '.sol' >> libs/remix-ui/editor/src/lib/providers/completion/contracts/contracts.txt"
},
"browserify": {
"transform": [
@ -197,6 +198,8 @@
"merge": "^2.1.1",
"monaco-editor": "^0.30.1",
"npm-install-version": "^6.0.2",
"prettier": "^2.7.1",
"prettier-plugin-solidity": "^1.0.0-beta.24",
"raw-loader": "^4.0.2",
"react": "^17.0.2",
"react-beautiful-dnd": "^13.1.0",
@ -261,6 +264,8 @@
"@types/ws": "^7.2.4",
"@typescript-eslint/eslint-plugin": "^4.32.0",
"@typescript-eslint/parser": "^4.32.0",
"@uniswap/v2-core": "^1.0.1",
"@uniswap/v3-core": "^1.0.1",
"ace-mode-lexon": "^1.*.*",
"ace-mode-move": "0.0.1",
"ace-mode-solidity": "^0.1.0",
@ -322,7 +327,7 @@
"onchange": "^3.2.1",
"request": "^2.83.0",
"rimraf": "^2.6.1",
"selenium-standalone": "^8.0.4",
"selenium-standalone": "^8.2.0",
"semver": "^6.3.0",
"solc": "0.7.4",
"tap-spec": "^5.0.0",

@ -4103,6 +4103,13 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@solidity-parser/parser@^0.14.3":
version "0.14.3"
resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.3.tgz#0d627427b35a40d8521aaa933cc3df7d07bfa36f"
integrity sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==
dependencies:
antlr4ts "^0.5.0-alpha.4"
"@svgr/babel-plugin-add-jsx-attribute@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906"
@ -4806,6 +4813,16 @@
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
"@uniswap/v2-core@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@uniswap/v2-core/-/v2-core-1.0.1.tgz#af8f508bf183204779938969e2e54043e147d425"
integrity sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==
"@uniswap/v3-core@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.1.tgz#b6d2bdc6ba3c3fbd610bdc502395d86cd35264a0"
integrity sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==
"@webassemblyjs/ast@1.8.5":
version "1.8.5"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
@ -5339,6 +5356,11 @@ ansistyles@~0.1.3:
resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539"
integrity sha512-6QWEyvMgIXX0eO972y7YPBLSBsq7UWKFAoNNTLGaOJ9bstcEL9sCbcjf96dVfNDdUsRoGOK82vWFJlKApXds7g==
antlr4ts@^0.5.0-alpha.4:
version "0.5.0-alpha.4"
resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a"
integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
@ -8167,10 +8189,10 @@ commander@^7.2.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
commander@^8.3.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
commander@^9.0.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c"
integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==
commondir@^1.0.1:
version "1.0.1"
@ -9740,6 +9762,11 @@ emittery@^0.8.1:
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860"
integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==
emoji-regex@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.1.0.tgz#d50e383743c0f7a5945c47087295afc112e3cf66"
integrity sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==
emoji-regex@^7.0.1:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
@ -9989,7 +10016,7 @@ escape-html@~1.0.3:
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
escape-string-regexp@4.0.0:
escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
@ -19118,6 +19145,23 @@ preserve@^0.2.0:
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=
prettier-plugin-solidity@^1.0.0-beta.24:
version "1.0.0-beta.24"
resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.24.tgz#67573ca87098c14f7ccff3639ddd8a4cab2a87eb"
integrity sha512-6JlV5BBTWzmDSq4kZ9PTXc3eLOX7DF5HpbqmmaF+kloyUwOZbJ12hIYsUaZh2fVgZdV2t0vWcvY6qhILhlzgqg==
dependencies:
"@solidity-parser/parser" "^0.14.3"
emoji-regex "^10.1.0"
escape-string-regexp "^4.0.0"
semver "^7.3.7"
solidity-comments-extractor "^0.0.7"
string-width "^4.2.3"
prettier@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64"
integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==
pretty-format@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"
@ -20850,12 +20894,12 @@ select-hose@^2.0.0:
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
selenium-standalone@^8.0.4:
version "8.0.8"
resolved "https://registry.yarnpkg.com/selenium-standalone/-/selenium-standalone-8.0.8.tgz#15f8202d2fed2bcc9264c10f2a8da4f71f85b377"
integrity sha512-2NCHoK12dbLbtXPIdMe1ljiLAMflJDBezPhjJBwmnYz5/yGjCPv2R9ojHO6W1ctD9DOlqyi3AxoAvlT2nmB7Fw==
selenium-standalone@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/selenium-standalone/-/selenium-standalone-8.2.0.tgz#378b9740fe84953083fa9c0b1d8dcbfc3bd8508c"
integrity sha512-gRFJm2A91sL0/4PavIsfTVNjyqNjk+zbdJg/zAYgTMjuoWJv+BlYJh+1UbEtyjt4YvZACYif1DFAzFjQapqiOA==
dependencies:
commander "^8.3.0"
commander "^9.0.0"
cross-spawn "^7.0.3"
debug "^4.3.1"
fs-extra "^10.0.0"
@ -20951,6 +20995,13 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semve
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.7:
version "7.3.7"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
dependencies:
lru-cache "^6.0.0"
send@0.17.1:
version "0.17.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
@ -21370,6 +21421,11 @@ solc@0.7.4:
semver "^5.5.0"
tmp "0.0.33"
solidity-comments-extractor@^0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19"
integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==
sort-keys@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
@ -21798,7 +21854,7 @@ string-width@^1.0.1, string-width@^1.0.2:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2:
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==

Loading…
Cancel
Save